以下代码:
public static void main(String args[]) throws NoSuchFieldException {
List<Integer> li = new ArrayList<Integer>();
ParameterizedType apType = (ParameterizedType) li.getClass().getGenericSuperclass();
Type[] typeArguments = apType.getActualTypeArguments();
int _i = 0;
for (Type type : typeArguments) {
System.out.format("parameterized type %d is: %s", ++_i, type);
}
}
生产:
parameterized type 1 is: E
- 我是否正确理解这是由于类型擦除的影响,并且它应该被解释为"未知",因为E是类型参数名称?
- 我觉得奇怪的是,我必须特别解释"E"这个名字(我想还有"S"、"U"等,如果有更多的话)。如果我的成绩是E级呢?此外,方法名是get_Actual_TypeArguments。考虑到类型参数像变量一样充当占位符,我发现方法应该返回变量的名称是非常奇怪的。我遗漏了什么吗?
另外,我不清楚为什么我可以将超类转换为ParameterizedType而不是类本身。试图将li.getClass()的结果强制转换为ParameterizedType会产生以下编译时错误:
要求:ParameterizedType发现:类其中CAP#1是一个新的类型变量:CAP#1从捕获扩展了List ?扩展列表
我看过这个相关的SO帖子,但它并没有给我启发。
一个泛型类的所有实例共享同一个运行时类:
new ArrayList<Integer>().getClass() == new ArrayList<String>().getClass()
换句话说,运行时不会跟踪用于实例化泛型类的实际类型参数。但是,它知道源代码中声明的类型,这就是getGenericSuperclass()及其友类返回的类型。所以如果你有一个类:
class Environment extends HashMap<String, Object> {
}
的表达式new Environment().getClass().getGenericSuperclass()
返回java.util.HashMap<java.lang.String, java.lang.Object>
相反,如果声明
class Environment<E> extends HashMap<String, E> {
}
相同的表达式返回
java.util.HashMap<java.lang.String, E>
所以,getGenericSuperclass返回源代码中声明的实际类型参数,但是这些类型参数可能包含在其他地方声明的类型变量。
另外,我不清楚为什么我可以将超类强制转换为ParameterizedType,而不是类本身。
ParametrizedType
对象表示编译时类型,具有非空的类型参数列表,Class
对象表示运行时类型(没有任何类型参数)。因此,Class
不是ParametrizedType