首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Erasure -编译后的泛型类型信息

Erasure -编译后的泛型类型信息
EN

Stack Overflow用户
提问于 2019-05-31 03:57:25
回答 2查看 55关注 0票数 2

我在一本书里偶然发现了下面的内容-

代码语言:javascript
复制
//Here, T is bound by Object by default.
class Gen<T> {
    T ob; // here, T will be replaced by Object

    Gen(T o) {
        ob = o;
    }

//Return ob.
    T getob() {
        return ob;
    }
}

代码语言:javascript
复制
// Here, T is bound by String.
class GenStr<T extends String> {
    T str; // here, T will be replaced by String
    GenStr(T o) {
      str = o;
    }
    T getstr() { return str; }
}

编译完这两个类后,Gen中的T将被Object替换。GenStr中的T将被String替换。您可以通过在编译后的类上运行javap来确认这一点。结果如下所示:

代码语言:javascript
复制
class Gen extends java.lang.Object{
    java.lang.Object ob;
    Gen(java.lang.Object);
    java.lang.Object getob();
}
class GenStr extends java.lang.Object{
    java.lang.String str;
    GenStr(java.lang.String);
    java.lang.String getstr();
}

但是,我看到了这个-

代码语言:javascript
复制
public class GenStr<T extends java.lang.String> {
  T str;

  GenStr(T);
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: aload_0
       5: aload_1
       6: putfield      #2                  // Field str:Ljava/lang/String;
       9: return

  T getstr();
    Code:
       0: aload_0
       1: getfield      #2                  // Field str:Ljava/lang/String;
       4: areturn
}

代码语言:javascript
复制
class Gen<T> {
  T ob;

  Gen(T);
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: aload_0
       5: aload_1
       6: putfield      #2                  // Field ob:Ljava/lang/Object;
       9: return

  T getob();
    Code:
       0: aload_0
       1: getfield      #2                  // Field ob:Ljava/lang/Object;
       4: areturn
}

为什么.class文件仍然显示形式类型参数<T>

EN

回答 2

Stack Overflow用户

发布于 2019-05-31 04:05:10

为什么.class文件仍然显示形式类型参数?

很简单:所以

  • 在编译时,编译器可以读取这样的.class文件,并理解相应的类是泛型的,并且可以在运行时在源代码中作为泛型
  • 使用,因此一些代码可以检查、很好地反映该类

的泛型性质。

类型擦除指的是不保留有关用于实例化的泛型类的特定类型的信息。但是这个类是泛型的信息需要在类文件中。否则,在编译器看不到Gen而只看到Gen.class的情况下,编译器如何知道Gen.java是泛型的呢?!

票数 3
EN

Stack Overflow用户

发布于 2019-05-31 04:06:00

有关类的类型信息仍然保留。有关单个实例的类型信息不是。

因此,您知道Gen有一个名为T的类级类型参数(名义上)。

您不知道Gen实例在运行时的T。您甚至不能从getob中确定它:这只能给出类型的下限(例如,如果getob返回一个String,则T可以是StringCharSequenceSerializableObject)。如果它返回null,那么T可以是任何东西。

您可以使用Java针对没有源代码的类编写代码,只有编译后的字节码。编译器需要有关这些类的泛型的信息,以便能够确保正确地使用它们的类型。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56384842

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档