为了账号安全,请及时绑定邮箱和手机立即绑定

Java泛型类型擦除:何时以及发生了什么?

Java泛型类型擦除:何时以及发生了什么?

宝慕林4294392 2019-05-25 16:42:40
Java泛型类型擦除:何时以及发生了什么?我在Oracle的网站上读到了Java的类型擦除。什么时候发生类型擦除?在编译时还是运行时?当班级加载?当类被实例化时?很多站点(包括上面提到的官方教程)都说在编译时会发生类型擦除。如果在编译时完全删除了类型信息,那么当调用使用泛型的方法而没有类型信息或错误的类型信息时,JDK如何检查类型兼容性?考虑以下示例:Say class 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());     }}我的猜测是类加载时会发生类型擦除,但这只是猜测。那么什么时候发生?
查看完整描述

4 回答

?
森林海

TA贡献2011条经验 获得超2个赞

类型擦除适用于泛型的使用。人们确实在类文件元数据说的方法/类型是否通用的,什么约束等,但仿制药的时候使用,他们转换成编译时检查和执行时间蒙上。所以这段代码:

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>界面本身仍然宣称自己是通用的。

编辑:只是为了澄清,编译器并保留有关的信息变量是一个List<String>-但您仍然无法找出T=String列表对象本身。


查看完整回答
反对 回复 2019-05-25
?
红颜莎娜

TA贡献1842条经验 获得超12个赞

Java语言中的泛型是一个非常好的指南。

泛型由Java编译器实现为称为擦除的前端转换。您可以(几乎)将其视为源到源的转换,从而将通用版本loophole()转换为非泛型版本。

所以,它是在编译时。JVM永远不会知道ArrayList你使用了哪个。

我还建议Skeet先生的答案是什么是Java中泛型的擦除概念?


查看完整回答
反对 回复 2019-05-25
  • 4 回答
  • 0 关注
  • 1711 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号