简体   繁体   English

运行时泛型类型确定

[英]Runtime generic type determination

Why this is happening. 为什么会这样。 If I pass anonymous generic class to type determination method - all is good. 如果我将匿名泛型类传递给类型确定方法 - 一切都很好。 But if I pass object in this method - console output is E. 但是如果我在这个方法中传递对象 - 控制台输出是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]);
}

Console: 安慰:

class java.lang.Integer

E

Please explain to me. 请向我解释。

The first invocation is passing an instance of a anonymous subclass of ArrayList<Integer> . 第一次调用是传递ArrayList<Integer>的匿名子类的实例。 So, it's similar to: 所以,它类似于:

class YourClass extends ArrayList<Integer>

and you invoking the method as: 并调用该方法:

printType(new YourClass());

The generic superclass of YourClass or the anonymous class in your case is ArrayList<Integer> only. YourClass的通用超类或您的案例中的匿名类仅为ArrayList<Integer> So, that output is clear. 所以,这个输出是清楚的。


As for your 2nd case, you are passing an instance of ArrayList<Integer> itself. 至于你的第二种情况,你传递的是ArrayList<Integer>本身的一个实例。 And definition of this class looks like: 这个类的定义如下:

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable

So, the generic superclass here is AbstractList<E> . 所以,这里的通用超类是AbstractList<E>

Instantiation of generic type share same Class instance: 泛型类型的实例化共享相同的Class实例:

Note that the all the instantiation of ArrayList share the same class at runtime: 请注意, ArrayList的所有实例化都在运行时共享同一个类:

new ArrayList<Integer>().getClass() == new ArrayList<String>().getClass();

The above comparison will give you true . 以上比较会给你true Because both the getClass() invocation gives back to you: 因为getClass()调用都给你回复:

class java.util.ArrayList

See JLS 8.1.2: Generic Classes and Type Parameters : 请参阅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. 泛型类声明定义了一组参数化类型(第4.5节),每个类型参数通过类型参数调用一个。 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 . 将导致变量b保持值为true

In other words, getGenericSuperClass() method will not give you the actual type argument you use while instantiating your class, but the type parameter used in the class it is extending. 换句话说, getGenericSuperClass()方法不会为您提供实例化类时使用的实际类型参数,而是它正在扩展的类中使用的类型参数。 Now, since the generic superclass of java.util.ArrayList is AbstractList<E> . 现在,由于java.util.ArrayList的通用超类是AbstractList<E> And hence the type parameter you get will be E only. 因此,您获得的类型参数将仅为E

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM