当前位置: 首页 > 知识库问答 >
问题:

Java泛型类型擦除,编译器输出与OCP书所说的不同

慕宏儒
2023-03-14
public class Crate<T> {
    private T contents;

    public Crate() {
    }

    public T emptyCrate() {
        return this.contents;
    }

    public void packCrate(T contents) {
        this.contents = contents;
    }

    public static void main(String[] args) {
        Crate<String> stringCrate = new Crate();
        stringCrate.packCrate("content");
        String content = (String)stringCrate.emptyCrate();
    }
}
public class Crate {
   private Object contents;
   public Object emptyCrate() {
      return contents;
   }
   public void packCrate(Object contents) {
      this.contents = contents;
   }

   public static void main(String[] args) {
        Crate stringCrate = new Crate();
        stringCrate.packCrate("content");
        String content = (String)stringCrate.emptyCrate();
    }
}
public class Crate<T> {
    private T contents;

    public Crate() {
    }

    public T emptyCrate() {
        return this.contents;
    }

    public void packCrate(T contents) {
        this.contents = contents;
    }

    public static void main(String[] args) {
        Crate<String> stringCrate = new Crate();
        stringCrate.packCrate("content");
        String content = (String)stringCrate.emptyCrate();
    }
}

共有1个答案

融宏伟
2023-03-14

这本书试图说明的一点是,运行时并不关心泛型类型参数。它通过在教学上向您“撒谎”类文件不包含任何泛型类型变量或参数来表明情况是这样的,这是可以理解的,但也不是真的。

类文件确实包含字段、方法和类声明中使用的类型变量和泛型参数。你甚至可以用反射得到它们!

// Both of these will print T
System.out.println(Crate.class.getTypeParameters()[0]);
System.out.println(Crate.class.getDeclaredField("contents").getGenericType());

只是运行时并不关心,例如,您是否将不是T的内容分配到一个假定为T类型的字段中。

Crate var1 = new Crate();
 类似资料:
  • 在stackoverflow中还没有讨论的情况下,我遇到了“不兼容类型”编译器错误(例如,为什么这个通用java代码不能编译?)。 我的期望很简单--我调用的是一个模板化方法,它不使用包含类的任何“泛型”类,因此它应该从方法参数中提取模板参数的类型,并且在所有情况下都应该编译--但我得到了“不兼容类型”编译器错误。 我注意到解决这个问题的奇怪方法--在方法参数中向泛型datatype添加“<?ex

  • 问题内容: 我是从Joshua Bloch的google I / O困惑者演讲中得到的。这是代码 这个main方法会引发异常,因为它是原始类型,因此in中的所有泛型都将被删除,因此最终调用而不是。 我的问题是,即使我打电话是不是应该把它调用的方法,因为由于类型擦除,这种方法是有效的并且是类型的不是? 问题答案: 被调用的方法是在编译时定义的,而不是在运行时定义的。 如果在构造函数调用中添加参数,则

  • 我有一个返回泛型的函数: 所以,当我试图匹配一个函数结果时,我的问题是: 我得到一个警告:“类型模式数组[CustomerInfo到[CustomerApplication到]]中的非变量类型参数CustomerApplication-DDTO未选中,因为它已被擦除消除。” 这是否意味着在Array[]中可以得到任何类型的数组?所以我已经阅读了关于ClassTag和TypeTag的文章,但是误解了

  • 问题内容: 我以为Java擦除会在编译时消除泛型类型,但是当我自己对其进行测试时,我意识到在Bytecode中有一些有关泛型类型的信息。 这是我的测试: 我写了2节课: 和 我编译了两个类,并在通用类的某个地方看到了这一行 在非泛型类中: 所以很明显我在字节码中有通用信息,那么这个擦除的东西是什么? 问题答案: 一些通用类型信息存储在属性中。请参阅JLS 4.8 和4.6以及JVM规范4.3.4。

  • 问题内容: 类型擦除应该擦除所有泛型信息…如果是这种情况,那么像GSON这样的库如何使用泛型来确定反序列化为哪种类型? 例如 这将反序列 化为 将反序列化为 因此以某种方式在运行时使用通用信息。 问题答案: 类型擦除不会擦除所有类型信息。它不会从类,字段,返回类型和参数定义中将其删除。保留以下示例中的类型信息: 这是可以通过反射实现的。您可以检查给定的是否是该类,将其强制转换为该类并获取类型信息。

  • 面对这一行代码,我感到非常困惑: 我知道什么