对于java type的理解

之前一直对Java Type与Class的概念感到模糊,通过上网翻阅资料,算是有个深刻的理解了。

术语说明

类型参数:指的是类型声明中的< >部分描述的参数列表 类型变量:如Map<K,V extends Number>,类型变量指的就是K,V。


由于Java的类型擦除机制,在运行时无法获取类型参数所表达的真实对象类型。但是,在编译期,类字节码中已经保存了源代码中的类型声明,包括类型参数。而这些源代码中的类型声明,就是使用Type这种数据类型来表达了。

Java中的Type描述的是源代码中各种类型的声明:

java.lang.reflect.Type是对源代码中所有类型声明的抽象,它只有一个抽象方法,用于描述类型名称:

default String getTypeName() {
    return toString();
}

java.lang.Class也实现了java.lang.reflect.Typejava.lang.Class在原有对字节码描述的基础上,加上了对源代码中普通类型声明描述,如对于String来说明,就是java.lang.Stringjava.lang.Class同时实现了java.lang.reflect.GenericDeclaration接口,即java.lang.Class对象可以获取自身类型声明中参数类型。如:

@Test
public void testForGenericDeclaration1() {
	TypeVariable<Class<Map>>[] typeParameters = Map.class.getTypeParameters();//获取到的就是Map接口定义中的<K,V>
	Assert.assertEquals("K",typeParameters[0].getTypeName());
	Assert.assertEquals("V", typeParameters[1].getTypeName());
}

java.lang.reflect.ParameterizedType是对源代码中使用泛型声明的类型抽象(如:Map<String,String>List<T>),因此它的接口声明中使用了三个抽象方法来描述这种类型的特征:

//用来描述泛型类型声明中的<>部分,如对于Map<String,String>来说,返回就是[Class<String>,Class<String>],对于List<T>来说,返回的就是[TypeVariable<Class<T>>]
Type[] getActualTypeArguments();

//获取泛型声明中的原始类型,对于`Map<String,String>`来说明就是Class<Map>,对于List<T>来说就是Class<List>
Type getRawType();

// 获取泛型声明是一个内部类,那么获取主类的类型声明。
Type getOwnerType();

java.lang.reflect.TypeVariable<D>描述的是类型声明中的类型变量部分。它的接口定义描述了它的特征:

//类型变量声明的上界,如T extends Number,T的上界就是Number
Type[] getBounds();

//获取类型变量的声明类
D getGenericDeclaration();

String getName();

java.lang.reflect.GenericArrayType描述的是泛型数组,它的组成元素是java.lang.reflect.ParameterizedTypejava.lang.reflect.TypeVariable<D>

WildcardType描述的是? extends Number? super Integer这种通配符类型。