作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我读到了 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.java
与 A.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/22770649/
我是一名优秀的程序员,十分优秀!