为什么在运行时不是所有的Java类型信息都被擦除? [英] Why are not all type information erased in Java at runtime?

查看:96
本文介绍了为什么在运行时不是所有的Java类型信息都被擦除?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我明显错误地理解Java泛型,到目前为止,Type Erasure删除了所有类型的信息,以至于在运行时完全没有任何东西存在。最近,我偶然发现了一个代码片段,我不得不问自己:这个工作如何进行?简化后,它显示为:

  import java.lang.reflect.ParameterizedType; 
import java.lang.reflect.Type;

public abstract class SuperClass< T> {

private final类型;

protected SuperClass(){
ParameterizedType parameterizedType =
(ParameterizedType)getClass()。getGenericSuperclass();
type = parameterizedType.getActualTypeArguments()[0];
}

public void tellMyType(){
System.out.println(我的类型参数是+ type);


code




  public class Example {

public static void main(String [] args){
SuperClass sc = new SuperClass< Integer>( ){};
sc.tellMyType();






$ b

执行Main Class的结果是我的类型参数是类java.lang.Integer



我们在这里可以看到的是,T的类型信息是也可以在运行时提供,这与我最初的理解相矛盾。

所以我的问题是:编译器为什么保留这个?这是否需要某些内部JVM行为,或者是否存在对此影响的合理解释? rel =noreferrer> http://www.artima.com/weblogs/viewpost.jsp?thread=208860 :


事实证明,虽然JVM将
追踪实体类型参数
作为泛型类的实例,但它
确实追踪实际类型参数
的子类泛型类。在
中换句话说,新的
ArrayList< String>()实际上只是一个
new ArrayList ()在运行时,如果一个类
扩展 ArrayList< String> ,那么
JVM知道 String List 的类型
参数的实际
类型参数。


在你的情况下,你正在创建一个参数化类型的匿名子类,所以类型信息被保留。请参阅文章以获得深入解释。


My obviously wrong understanding of Java Generics was up to now, that Type Erasure removes all type information such that there is nothing left at all at runtime. Recently I stumbled upon a code fragment where I had to ask myself: How the hack does this work? Simplified, it presents as:

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);
    }    
}

and

public class Example {

    public static void main(String[] args) {
        SuperClass sc = new SuperClass<Integer>(){};
        sc.tellMyType();
    }
}

Executing the Main Class results in Hi, my type parameter is class java.lang.Integer.

What we can see here is, that the type information of T is also available at runtime, which contradicts my initial understanding.

So my question is: Why does the compiler keep this? Is this required for some internal JVM behavior or is there any reasonable explanation for this effect?

解决方案

From 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 new ArrayList() at runtime, if a class extends ArrayList<String>, then the JVM knows that String is the actual type argument for List's type parameter.

In your case, you are making an anonymous subclass of the parameterized type, so the type information is retained. See the article for an in-depth explanation.

这篇关于为什么在运行时不是所有的Java类型信息都被擦除?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆