整理自:https://blog.csdn.net/qq_30770095/article/details/79016257
Type是一个空接口,所有类型的公共接口(父接口)。其意义表示Java所有类型,这里所谓的类型是从Java整个语言角度来看的,比如原始类型(Class类型)、参数化类型(泛型)、类型变量及其泛型数组等,可以理解为Class是Java对现实对象的抽象,而Type是对Java语言对象的抽象。
Type的来历
我们知道,Type是JDK5开始引入的,其引入主要是为了泛型,没有泛型的之前,只有所谓的原始类型。此时,所有的原始类型都通过字节码文件类Class类进行抽象。Class类的一个具体对象就代表一个指定的原始类型。
泛型出现之后,也就扩充了数据类型。从只有原始类型扩充了参数化类型、类型变量类型、泛型数组类型,也就是Type的子接口。
那为什么没有统一到Class下,而是增加一个Type呢?(Class也是种类的意思,Type是类型的意思)
是为了程序的扩展性,最终引入了Type接口作为Class,ParameterizedType,GenericArrayType,TypeVariable和WildcardType这几种类型的总的父接口。这样实现了Type类型参数接受以上五种子类的实参或者返回值类型就是Type类型的参数。
1.原始类型
Class表示的是原始类型。Class类的对象表示JVM中的一个类或者接口,每个java类在JVM都表现为一个Class对象。可以通过“类名.Class”、“对象.getClass()”或者Class.forName("类名")等方法获取到Class对象。数组也被映射为Class对象,所有元素类型相同且维度相同的数组都共享同一个Class对象。
2.参数化类型
ParameterizedType表示的是参数化类型,例如List<String>、Map<Integer,String>、Service<User>这种带有泛型的类型。
3.类型变量
TypeVariable表示的是类型变量。例如List<T>中的T就是类型变量
4.范型数组
GenericArrayType表示的是数组类型且组成元素是ParameterizedType或者是TypeVariable,例如List<String>[] 或 T[]。
5.通配符类型
WildcardType表示的是通配符泛型,例如<? extends Number>
ParmeterizedType(参数化类型)
即为参数化类型,就是将类型进行参数化,把类型当做参数传入
参数化类型一般用来表示如List<T>,注意应该当成一个整体来进行看待
parameterizedType表示的类型非常的简单,只要带着泛型,除了不可以是数组和本类上定义的泛型以外,其他都被列入ParameterizedType的范围。
具体的方法可以自行查询API,这里不进行介绍,只是帮助理解。
public class Type{
public List<String> list;
private List<String>[] list1;
private List list2;
Map.Entry<String,Integer> entry;
String str = new String();
T t;
}
public static void main(String[] args) throws ClassNotFoundException {
Class<Type> type = (Class<Type>) Class.forName("test.Type");
Field[] fields = type.getDeclaredFields();
for (Field field : fields) {
System.out.println("field name is :" + field.getName());
System.out.print("instanceof ParameterizedType");
System.out.println(" " + (field.getGenericType() instanceof ParameterizedType));
System.out.println("type "+field.getGenericType().getClass());
if ("entry".equals(field.getName())) {
ParameterizedType t = (ParameterizedType) field.getGenericType();
System.out.println("ownerType "+t.getOwnerType());
System.out.println("rawType "+t.getRawType());
Type[] actualTypeArguments = t.getActualTypeArguments();
for (Type type2 : actualTypeArguments) {
System.out.println("actualTypeArguments :" + type2.getTypeName());
}
}
System.out.println();
}
}
运行结果
field name is :list
instanceof ParameterizedType true
type class sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl
field name is :list1
instanceof ParameterizedType false
type class sun.reflect.generics.reflectiveObjects.GenericArrayTypeImpl
field name is :list2
instanceof ParameterizedType false
type class java.lang.Class
field name is :entry
instanceof ParameterizedType true
type class sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl
ownerType interface java.util.Map
rawType interface java.util.Map$Entry
actualTypeArguments :java.lang.String
actualTypeArguments :java.lang.Integer
field name is :str
instanceof ParameterizedType false
type class java.lang.Class
field name is :t
instanceof ParameterizedType false
type class sun.reflect.generics.reflectiveObjects.TypeVariableImpl
解释
- List<String> list 是ParameterizedType。
- List<String>[] list1由于是数组,所以不是ParameterizedType,应该是GenericArrayType。
- List list2由于没有带泛型,所以也不是ParameterizedType,应该是Class,也就是原始类型。
- Map.Entry<String,Integer> entry 是parameterizedType,我们进一步使用了ParameterizedType的3个方法演示给大家看。我们可以看到ownerType是Entry的外部类Map。这也印证了获取到的类型Map为原类型,Map.Entry是其成员之一,而rawType则是其自身类型。getActualTypeArguments()获取到的Type数组则是泛型中的所有类型。(例如Map<k,v>则获取到的数组中包含k,v这两个类型。并且k在前,v在后。)
- String str = new String();由于没有带泛型所有不是parameterizedType,应该是Class。
- T t 由于是本类上定义的泛型,所以也不行,应该是类型变量。
TypeVariable(类型变量)
public class Type<T extends Integer> {
T t;
}
public static void main(String[] args) throws ClassNotFoundException {
Class<Type> type = (Class<Type>) Class.forName("test.Type");
Field[] fields = type.getDeclaredFields();
for (Field field : fields) {
System.out.println("field name is :" + field.getName());
System.out.println("type " + field.getGenericType().getClass());
TypeVariable t = (TypeVariable) field.getGenericType();
System.out.println("declaration " + t.getGenericDeclaration());
System.out.println("up bound " + t.getBounds()[0]);
}
}
field name is :t
type class sun.reflect.generics.reflectiveObjects.TypeVariableImpl
declaration class test.Type
up bound class java.lang.Integer
解释
declaration:声明该类型遍历的类,上边界Integer,如果没有声明上边界,则默认为Object。
GenericArrayType(泛型数组类型)
顾名思义,只要是带泛型的,并且是数组的那就属于GenericArrayType的范畴。
WildcardType(通配符类型)
表示通配符类型参数。
WildcardType是依托于ParameterizedType和GenericArrayType
例如:
Class<?>
List<? extends Number>
Set<? super T>