子接口:ParameterizedType, TypeVariable, GenericArrayType, WildcardType
实现类:Class
Raw types:原生类型
带泛型<>的,基本都是;
主要有3个方法:
Type[] getActualTypeArguments():
获得<>中实际类型,因为可能有多个类型参数,例如Map
注意:无论<>中有几层<>嵌套,这个方法仅仅脱去最外层的<>,之后剩下的内容就作为这个方法的返回值,所以其返回值类型不一定。
1、List
2、List
3、List
4、List a4;返回的是WildcardType类型;
5、List
注意: ArrayList与ArrayList
上面的几条暂时看不懂,没关系,因为你还没看到其他的几个,回头看就懂了
Type getRawType()
获得<>前面实际类型,即Map
Type getOwnerType()
知道这个类型是某个类型所属,获得这个所有者类型,否则返回null;这个我没用过,不是太懂;
public static void main(String[] args)
{
Method method = new GenericDemo().getClass().getMethod("applyMethod",Map.Entry.class);
Type[] types = method.getGenericParameterTypes();
ParameterizedType pType = (ParameterizedType)types[0];
//返回所有者类型,打印结果是interface java.util.Map
System.out.println(pType.getOwnerType());
}
public static void applyMethod(Map.Entry mapEntry){
}
//Map接口就是Map.Entry的所有者
描述类型,表示泛指任意或相关一类类型,也可以说是狭义上的泛型(泛型指某一类类型),一般用大写字母作为变量,比如K、V、E等
四个方法:
Type[] getBounds()
获得该类型变量的上限(上边界),若无显示定义(extends),默认为Object,类型变量的上限可能不止一个,因为可以用&符号限定多个(这其中有且只能有一个 为类或抽象类,且必须放在extends的第一个,即若有多个上边界,则第一个&后必为接口)。
当有多个泛型参数时,就有多个TypeVariable,每个TypeVariable有多个上限,取第一个。
D getGenericDeclaration()
获取声明该类型变量实体(即获得类、方法或构造器名)
String getName()
获得名称,即K、V、E之类名称
AnnotatedType[] getAnnotatedBounds()
这个不知道
返回annotatedtype对象表示表示该型变量表示的类型参数的上界类型使用一个数组。
描述的是ParameterizedType类型以及TypeVariable类型数组,即形如:classA
无论从左往右有几个[]并列,这个方法仅仅脱去最右边的[]之后剩下的内容就作为这个方法的返回值
一个方法:
Type getGenericComponentType()
获得这个数组元素类型,即获得:A[T][] -> A[T],A[T] -> T
通配符表达式,Type子接口,但是Java中并没有WildcardType类型;
两个方法:
Type[] getUpperBounds()
获得泛型表达式上界(上限)
Type[] getLowerBounds()
获得泛型表达式下界(下限)
Java中的所有类型包括:
1、raw type:原始类型,对应Class;
2、parameterized types:参数化类型,对应ParameterizedType;
3、array types:数组类型,对应GenericArrayType;
4、type variables:类型变量,对应TypeVariable;
5、primitive types:基本类型,仍然对应Class;
1)、1中的Class,不仅仅只平常所指的类,还包括数组、接口、注解、枚举等结构;
2)、3中的数组类型GenericArrayType,应该指的是2、4类型数组,而不是一般我们说的数组,我们一般说的数组是指1、5类型数组,他们还是1、也就是Class类型;
3)、List
这里的List就是ParameterizedType,
T就是TypeVariable,
T ? extends就是WildcardType(注意:WildcardType不是java类型,而是一个表达式 ),
整个List
可以声明类型变量的实体的公共接口,也就是说,只有实现了该接口才能在对应的实体上声明(定义)类型变量,这些实体目前只有三个:Class(类)、Construstor(构造器)、Method(方法);
所有可以声明/定义类型变量(TypeVariable)的实体的公共父接口,其直接实现子类:java.lang.reflect子包中的:Class,Method,Constructor,所以,这三个对应的类上、方法上、构造器上可以声明(定义)类型变量,GenericDeclaration的直接实现子类没有Field类,所以属性上面不能定义类型变量。
一个方法:
TypeVariable[] getTypeParameters()
获得声明列表上的类型变量数组
public class Main<K extends classA & interfaceB, V> {
classA[][] key;
V value;
public static void main(String[] args) throws Exception
{
TypeVariable[] types = Main.class.getTypeParameters();
for(TypeVariable type : types){
System.out.println(type.getName());
}
}
}
//输出结果
K
V
参考1:Java源码解析(附录)(1) —— ParameterizedType
参考2:Java源码解析(附录)(2) —— TypeVariable
参考3:Java源码解析(附录)(3) —— GenericDeclaration
参考4:Java源码解析(附录)(4) —— GenericArrayType
参考5:Java源码解析(附录)(5) —— WildcardType