运行时泛型类型确定

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

请给我解释一下。

你想要做什么? - Crickcoder
你正在打印你的列表的类型参数。 - Philipp Sander
我正在尝试在运行时获取类型参数。 - arsen_adzhiametov
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: 泛型类和类型参数

A generic class declaration defines a set of parameterized types (§4.5), one for each possible invocation of the type parameter section by type arguments. All of these parameterized types share the same class at run time.

For instance, executing the code:

    Vector<String>  x = new Vector<String>(); 
    Vector<Integer> y = new Vector<Integer>(); 
    boolean b = x.getClass() == y.getClass();

will result in the variable b holding the value true.

换句话说,getGenericSuperClass()方法不会给你实例化类时使用的实际类型参数,而是用于扩展的类中使用的类型参数。现在,由于java.util.ArrayList的泛型超类是AbstractList<E>,因此您得到的类型参数将仅为E

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接