反射允许你在运行时分析任意的对象。如果对象是泛型类的实例,关于泛型类型参数则得不到太多信息,因为它们会被擦除。
泛型Class类
Class 类是泛型的。例如,String.class 实际上是一个 Class
类型参数十分有用,这是因为它允许 Class
T newInstance();
T cast(Object obj);
T[] getEnumConstants();
Class<? super T> getSuperclass();
Constructor<T> getConstructor(Class...paramentTypes);
Constructor<T> getDecalredConstructor(Class...paramentTypes);
newInstance 方法返回一个实例,这个实例所属的类由默认的构造器获得。它的返回类型目前被声明为T,其类型与 Class
如果给定的类型确实是 T 的一个子类型,cast 方法就会返回一个现在声明为类型 T 的对象,否则,抛出一个 BadCastException 异常。
Class 的 getSuperclass()
方法返回的 Class 类型是 Class<? super T>:
Class<? super String> sup = String.class.getSuperclass();
如果这个类不是 enum 类或类型 T 的枚举值的数组,getEnumConstants 方法将返回 null。
最后,getConstructor 与 getdeclaredConstructor 方法返回一个 Constructor
虚拟机中的泛型类型信息
Java 泛型的卓越特性之一是在虚拟机中泛型类型的擦除。令人感到奇怪的是,擦除的类仍然保留一些泛型祖先的微弱记忆。例如,原始的Pair类知道源于泛型类 Pair
可以使用反射 API 来确定:
- 这个泛型方法有一个叫做 T 的类型参数。
- 这个类型参数有一个子类型限定,其自身又是一个泛型类型。
- 这个限定类型有一个通配符参数。
- 这个通配符参数有一个超类型限定。
- 这个泛型方法有一个泛型数组参数。
为了表达泛型类型声明,使用 java.lang.reflect 包中提供的接口 Type。