为什么会这样。如果我将匿名泛型类传递给类型确定方法 - 一切都很好。但是如果我在这个方法中传递对象 - 控制台输出是E.
public static void main(String[] args) {
printType(new ArrayList<Integer>() {});
printType(new ArrayList<Integer>());
}
public static void printType(final List<?> list) {
System.out.println(((ParameterizedType) list.getClass().getGenericSuperclass()).getActualTypeArguments()[0]);
}
控制台:
class java.lang.Integer
E
请向我解释。
答案 0 :(得分:7)
第一次调用是传递ArrayList<Integer>
的匿名子类的实例。所以,它类似于:
class YourClass extends ArrayList<Integer>
并且您将该方法调用为:
printType(new YourClass());
YourClass
的通用超类或您案例中的匿名类仅为ArrayList<Integer>
。所以,这个输出是清楚的。
至于你的第二个案例,你正在传递一个ArrayList<Integer>
本身的实例。这个类的定义如下:
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
因此,这里的通用超类是AbstractList<E>
。
通用类型的实例化共享相同的Class
实例:
请注意,ArrayList
的所有实例化都在运行时共享同一个类:
new ArrayList<Integer>().getClass() == new ArrayList<String>().getClass();
以上比较将为您提供true
。因为getClass()
调用都会回复给您:
class java.util.ArrayList
请参阅JLS 8.1.2: Generic Classes and Type Parameters:
泛型类声明定义了一组参数化类型 (§4.5),每个可能的类型参数部分调用一个 按类型参数。所有这些参数化类型都共享相同的内容 在课程时间上课。
例如,执行代码:
Vector<String> x = new Vector<String>(); Vector<Integer> y = new Vector<Integer>(); boolean b = x.getClass() == y.getClass();
将导致变量
b
保持值true
。
换句话说,getGenericSuperClass()
方法不会为您提供实例化类时使用的实际类型参数,而是在它所扩展的类中使用的类型参数。现在,由于java.util.ArrayList
的通用超类是AbstractList<E>
。因此,您获得的类型参数仅为E
。