5

为什么会这样。如果我将匿名泛型类传递给类型确定方法 - 一切都很好。但是如果我在这个方法中传递对象 - 控制台输出是 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

请给我解释一下。

4

1 回答 1

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:泛型类和类型参数

泛型类声明定义了一组参数化类型(第 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.ArrayListis AbstractList<E>。因此,您获得的类型参数将是E唯一的。

于 2013-09-27T09:31:46.097 回答