到目前为止,我对 Java 泛型的明显错误理解是,Type Erasure 会删除所有类型信息,这样在运行时就什么都没有了。最近我偶然发现了一个代码片段,我不得不问自己:这个 hack 是如何工作的?简而言之,它表现为:
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
public abstract class SuperClass<T> {
private final Type type;
protected SuperClass(){
ParameterizedType parameterizedType =
(ParameterizedType) getClass().getGenericSuperclass();
type = parameterizedType.getActualTypeArguments()[0];
}
public void tellMyType(){
System.out.println("Hi, my type parameter is " + type);
}
}
和
public class Example {
public static void main(String[] args) {
SuperClass sc = new SuperClass<Integer>(){};
sc.tellMyType();
}
}
执行主类导致嗨,我的类型参数是class java.lang.Integer
。
这里我们可以看到,T 的类型信息在运行时也是可用的,这与我最初的理解相矛盾。
所以我的问题是:为什么编译器会保留这个?这是某些内部 JVM 行为所必需的,还是对此效果有任何合理的解释?
最佳答案
来自 http://www.artima.com/weblogs/viewpost.jsp?thread=208860 :
It turns out that while the JVM will not track the actual type arguments for instances of a generic class, it does track the actual type arguments for subclasses of generic classes. In other words, while a new
ArrayList<String>()
is really just a newArrayList()
at runtime, if a class extendsArrayList<String>
, then the JVM knows thatString
is the actual type argument forList
's type parameter.
在您的情况下,您正在创建参数化类型的匿名子类,因此保留了类型信息。请参阅文章以获得深入的解释。
关于java - 为什么 Java 在运行时不会删除所有类型信息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2320658/