Java 反射篇(三)泛型 API 总结
泛型术语
泛型涉及的术语比较多,其与反射接口的对应关系如下:
术语 | 中文含义 | 举例 | 反射接口 | 备注 |
---|---|---|---|---|
Generic type | 泛型 | List<E> |
ParameterizedType |
|
Parameterized type | 参数化类型 | List<String> |
ParameterizedType |
|
Raw type | 原始类型 | List |
ParameterizedType#getRawType |
该方法虽然返回 Type 类型,但实际类型是 Class ,可以强转使用:(Class<?>) type 。 |
Unbounded wildcard type | 无限制通配符类型 | List<?> |
ParameterizedType |
|
Bounded wildcard type | 有限制通配符类型(上限) | List<? extends Number> |
ParameterizedType |
|
Bounded wildcard type | 有限制通配符类型(下限) | List<? super Number> |
ParameterizedType |
|
wildcard type | 通配符类型 | ? |
WildcardType |
|
Formal type parameter | 形式类型参数 | E |
TypeVariable |
|
Actual type parameter | 实际类型参数 | String |
ParameterizedType#getActualTypeArguments |
该方法虽然返回 Type[] 类型,但各元素实际类型是 Class ,可以强转使用:(Class<?>) type 。 |
Bounded type parameter | 有限制类型参数 | <E extends Number> |
||
Recursive type bound | 递归类型限制 | <T extends Comparable<T>> |
||
Generic method | 泛型方法 | static <E> List<E> asList(E[] a) |
||
Type token | 类型令牌 | String.class |
泛型 API
java.lang.reflect.Type
JDK 1.5 引入了泛型特性,一同引入的还有 Java Type
类型体系。其中 java.lang.reflect.Type
接口作为核心,是 Java 编程语言中所有类型的通用超级接口(common superinterface),这些类型包括:
- 原始类型(raw types)
- 参数化类型(parameterized types)
- 数组类型(array types)
- 八大原始类型(primitive types)
- 类型变量(type variables)
调整后新引入的五个接口如下:
1 | java.lang.reflect.Type |
它们的核心方法如下:
类、字段、方法、构造方法也相应增加了一组方法,用于获取 Type
:
java.lang.Class
1
2
3
4
5
6
7// 获取普通 Class
Class<? super T> getSuperclass()
Class<?>[] getInterfaces()
// 获取 Type
Type getGenericSuperclass()
Type[] getGenericInterfaces()java.lang.reflect.Field
1
2
3
4
5// 获取普通 Class
Class<?> getType()
// 获取 Type
Type getGenericType()java.lang.reflect.Method
1
2
3
4
5
6
7
8
9// 获取普通 Class
Class<?> getReturnType()
Class<?>[] getParameterTypes()
Class<?>[] getExceptionTypes()
// 获取 Type
Type getGenericReturnType()
Type[] getGenericParameterTypes()
Type[] getGenericExceptionTypes()java.lang.reflect.Constructor
1
2
3
4
5
6
7// 获取普通 Class
Class<?>[] getParameterTypes()
Class<?>[] getExceptionTypes()
// 获取 Type
Type[] getGenericParameterTypes()
Type[] getGenericExceptionTypes()
java.lang.reflect.GenericDeclaration
同时新增的接口还有 java.lang.reflect.GenericDeclaration
,用于获取 TypeVariable
:
从源码看,只有三个类实现了该接口(见下图):
java.lang.Class
java.lang.reflect.Method
java.lang.reflect.Constructor
因此只有这三个地方可以声明为泛型,并获取其类型参数(type variables)集合:K
、V
类型(例如
class
、interface
)1
2
3public class Test<K, V> { ... }
public interface Test<K, V> { ... }构造方法(
Constructor
)1
public <K, V> Test(K k, V v) { ... }
方法(
Method
)1
public <K, V> K test(V v) { ... }
类、方法、构造方法也相应增加了一个方法,用于获取 TypeVariable
:
java.lang.Class
java.lang.reflect.Method
java.lang.reflect.Constructor
1 | TypeVariable<?>[] getTypeParameters() |
例子
下面是几个获取 Type
的例子,先创建三个类:BaseMapper
、PersonMapper
、Person
1 | public interface BaseMapper<T extends Serializable & Comparable<T>, K extends Serializable> { |
例子一
1 |
|
三个 Type
变量的内容如下:
例子二
接下来看下 ParameterizedType
的使用,可以用于获取泛型的原始类型(Raw type)、实际类型参数(Actual type parameter)列表:
1 |
|
genericInterface
变量的内容如下,接口返回类型虽然为 Type
,实际类型为 ParameterizedType
,因此可以强转。该泛型变量的原始类型、实际类型参数列表如下,实际都为 Class
类型,因此可以强转 (Class<?>) type
:
例子三
WildcardType
的使用:
1 |
|
Type
类型变量 genericParameterType
的内容如下,实际类型是 ParameterizedType
,其 ?
通配符是 WildcardType
:
例子四
TypeVariable
的使用:
1 |
|
Type
类型变量 genericReturnType
的内容如下,实际类型是 TypeVariable
,
例子五
定义一个泛型工具类,用于获取 T.class
:
1 | import java.lang.reflect.ParameterizedType; |
参考
API:
- https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/Type.html
- https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/ParameterizedType.html
- https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/TypeVariable.html
- https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/WildcardType.html
- https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/GenericArrayType.html