以下代码:
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
另外,我不清楚为什么我可以将超类强制转换为 ParameterizedType 而不是类本身。尝试将 li.getClass()的结果转换为 ParameterizedType 会产生以下编译时错误:
必需:ParameterizedType 发现:上课 其中CAP#1是一个新的类型变量: CAP#1扩展了List的捕获?扩展名单
我见过这个relevant SO post,但它没有启发我。
答案 0 :(得分:4)
泛型类的所有实例共享相同的运行时类:
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
。