第一次调用是传递一个匿名子类的实例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:泛型类和类型参数:
泛型类声明定义了一组参数化类型(第 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
is AbstractList<E>
。因此,您获得的类型参数将是E
唯一的。