gpt4 book ai didi

Java泛型类型删除: when and what happens?

转载 作者:太空宇宙 更新时间:2023-11-04 14:25:34 24 4
gpt4 key购买 nike

我读到了有关 Java 类型删除的内容 on Oracle's website .

什么时候发生类型删除?在编译时还是运行时?类什么时​​候加载?类何时实例化?

很多网站(包括上面提到的官方教程)都说类型删除发生在编译时。如果在编译时完全删除类型信息,那么当调用没有类型信息或类型信息错误的使用泛型的方法时,JDK如何检查类型兼容性?

考虑以下示例:说类 A有一个方法,empty(Box<? extends Number> b) 。我们编译A.java并获取类文件A.class .

public class A {
public static void empty(Box<? extends Number> b) {}
}
public class Box<T> {}

现在我们创建另一个类B它调用方法 empty带有非参数化参数(原始类型):empty(new Box()) 。如果我们编译B.javaA.class在类路径中,javac 足够聪明,可以发出警告。所以A.class 存储在其中的一些类型信息。

public class B {
public static void invoke() {
// java: unchecked method invocation:
// method empty in class A is applied to given types
// required: Box<? extends java.lang.Number>
// found: Box
// java: unchecked conversion
// required: Box<? extends java.lang.Number>
// found: Box
A.empty(new Box());
}
}

我的猜测是,加载类时会发生类型删除,但这只是猜测。那么什么时候发生呢?

最佳答案

类型删除适用于泛型的使用。类文件中肯定有元数据来说明方法/类型是否泛型,以及约束是什么等。但是当使用泛型时,它们会被转换分为编译时检查和执行时强制转换。所以这段代码:

List<String> list = new ArrayList<String>();
list.add("Hi");
String x = list.get(0);

被编译成

List list = new ArrayList();
list.add("Hi");
String x = (String) list.get(0);

在执行时,无法发现 T=String对于列表对象 - 该信息消失了。

...但是 List<T>接口(interface)本身仍然标榜自己是通用的。

编辑:为了澄清,编译器确实保留了有关变量 List<String> 的信息。 - 但你还是找不到T=String对于列表对象本身。

关于Java泛型类型删除: when and what happens?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26709208/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com