反射与范型
由于类型擦除,反射无法得到关于范型类型参数的信息。
-
范型的Class类
在Java的反射库中,
Class
类是范型的,例如String.class
将会得到一个Class<String>
。有了这些类型信息,则可以在调用反射方法时,进行更少的类型转换。 -
使用
Class<T>
进行参数匹配
编译器很聪明,它可以从Class<T>
中抽取类型信息,推测一些确定的类型。public static <T> Pair<T> makePair(Class<T> c) throws InstantiationException, IllegalAccessException { return new Pair<>(c.newInstance(), c.newInstance); }
调用
makePair(Employee.class)
,编译器可以推测出返回值为Pair<Employee>
。 -
虚拟机中的范型信息
虽然范型信息在虚拟机中被擦除了,但是反射仍然可以得到一些范型信息。虚拟机中的Pair
的RAW TYPE类知道自己源于一个Pair<T>
,但是它不知道T
是什么,是String
,还是Employee
。
范型方法public static <T extends Comparable<? super T>> T min(T[] a)
。
类型擦除后,方法变为public static Comparable min(Comparable[] a)
。
通过反射,仍然可以得到部分范型信息:- 这个方法有一个叫做T的类型参数。
- 这个类型参数有一个子类型的限定(extends),子类型又是一个范型类型。
- 限定类型有一个通配符参数。
- 通配符有个超类型限定。
- 方法参数有个是范型数组。
相关的类和方法:
Class.getTypeParameters()
Class.getGenericSuperClass()
Class.getGenericInterfaces()
Method.getTypeParameters()
Method.getGenericReturnType()
Method.getGenericParameterTypes()
TypeVariable.getName()
TypeVariable.getBounds()
WildcardType.getUpperBounds()
WildcardType.getLowerBounds()
ParameterizedType.getRawType()
ParameterizedType.getActualTypeArguments()
ParameterizedType.getOwnerType()
GenericArrayType.getGenericComponentType()
网友评论