Java泛型 - 擦除机制

时间:2017-05-27 12:58:03

标签: java generics type-erasure

说..,Java编译器擦除所有类型信息,并用它们的上限(如果提到)或Object替换所有出现的那些。

我的问题是:这里没有插入演员阵容。转换发生在稍后当针对此类型无信息类编译其他类时,其中,根据其他类补充的类型参数,重新编译泛型类(第二次)并且所有强制转换都已放置到位并且该课程已准备好运行时间..对吧?

3 个答案:

答案 0 :(得分:4)

不,该课程未重新编译。演员表发生在具体类型和泛型类型之间的边界上。

如果你想弄明白,你可以考虑使用泛型类作为原始类型(即没有泛型)。例如ArrayList

List l = new ArrayList(); // An `ArrayList<String>` before generics.

l.add("Hello");
String s = (String) l.get(0);

在已知具体类型的地方插入演员表(在本例中为String)。它们插入到ArrayList类中,并且实际上并不需要它。

答案 1 :(得分:0)

  

稍后在针对此编译其他类时进行转换   输入info-free class,

不,演员阵容是在课堂本身的编译阶段进行的 编译后的类不应该根据依赖的类进行更改。

看看这个方法:

public class TestCast {

    public void doSomething(){
       List<Integer> values = new ArrayList<>();
       values.add(1);
       Integer value = values.get(0);
    }
}

以下是TestCast已编译类的反汇编方法(使用javap工具完成):

public void doSomething();
   Code:
      0: new           #15                 // class java/util/ArrayList
      3: dup
      4: invokespecial #17                 // Method java/util/ArrayList."<init>":()V
      7: astore_1
      8: aload_1
      9: iconst_1
     10: invokestatic  #18                 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     13: invokeinterface #24,  2           // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
     18: pop
     19: aload_1
     20: iconst_0
     21: invokeinterface #30,  2           // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
     26: checkcast     #19                 // class java/lang/Integer
     29: astore_2
     30: return

编译器确实添加了强制转换:

 26: checkcast     #19                 // class java/lang/Integer

答案 2 :(得分:0)

到目前为止,没有提到其他答案的是桥梁方法。

e.g。

public class GenericTest implements Comparable<GenericTest>{

    @Override
    public int compareTo(GenericTest o) {
        return 0;
    }
}

编译器实际上会创建两个方法。投射和转发的int compareTo(Object);以及预期的int compareTo(GenericTest)