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

2023-12-08

我读到了有关 Java 类型擦除的内容在甲骨文网站上.

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

很多网站(包括上面提到的官方教程)都说类型擦除发生在编译时。如果在编译时完全删除类型信息,那么当调用没有类型信息或类型信息错误的使用泛型的方法时,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 with A.class在类路径中,javac 足够聪明,可以发出警告。所以A.class has其中存储了一些类型信息。

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());
    }
}

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


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

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>接口本身仍然标榜自己是通用的。

编辑:只是为了澄清,编译器确实保留了有关variable成为一个List<String>- 但你还是无法发现T=String对于列表对象本身。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java 泛型类型擦除:何时以及会发生什么? 的相关文章

随机推荐

  • 在运行时动态选择一个类

    我试图提出一个解决方案 在运行时根据消息类型选择处理 消息 的类 我知道我可以使用这样的东西 if msg type A MsgAProcessor execute message else if msg type B MsgBProces
  • IntelliJ IDEA 2016.3.4:构建过程异常终止

    我在 Intellij IDEA 中构建新的 java 项目时遇到错误 错误 构建过程异常终止 C Program Files Java jdk1 8 0 121 bin java Xmx700m Djava awt headless tr
  • 如何在 .NET SslStream 中为客户端身份验证指定接受的证书

    我正在尝试使用 Net System Security SslStream 类来处理具有客户端身份验证的 SSL TLS 流的服务器端 为了执行握手 我使用以下代码 SslStream sslStream new SslStream inn
  • 如何在 bash 中格式化数字,可能使用 printf ?

    这个如此简单的脚本失败了 bin bash n 1 printf v fn 05d n echo fn with 3 printf Illegal option v 为什么 Ubuntu 14 04 根据 Joe 这似乎是重复的以 scri
  • 为什么自定义函数引用一直指向旧函数

    我在 javascript设计模式 中找到了这个示例 并与以下代码的行为混淆 此代码创建一个自定义函数 var scareMe function alert Boo scareMe function alert Double boo 现在我
  • 使用
  • 而不包含
  • Closed 这个问题需要多问focused 目前不接受答案 插入有什么危险 li li 进入页面而不将项目包含在 ul 堵塞 例如 div style border solid 1px red li Item li li Another
  • 使用 Jenkins 执行 NUnit

    早上好 我想配置 Jenkins 服务器以使用插件运行 NUnitJenkins NUnit 插件但我尝试了很多东西但不起作用 我单击按钮 添加构建步骤 gt gt 执行Windows批处理命令但我在这里看到了http stackoverf
  • 我可以向现有静态类添加扩展方法吗?

    我很喜欢 C 中的扩展方法 但在向静态类添加扩展方法方面还没有取得任何成功 例如Console 例如 如果我想添加一个扩展Console 称为 WriteBlueLine 这样我就可以去 Console WriteBlueLine This
  • 在多行插入中使用 LAST_INSERT_ID()

    是否可以在插入查询中使用 LAST INSERT ID INSERT INTO mytable col1 col2 VALUES val1 null val2 LAST INSERT ID 尝试上面的 LAST INSERT ID 返回 0
  • 在表格边框上获取 Flutter DataTable 边框半径时出现问题

    我有一个DataTable我想添加一个边框半径 阅读完此内容后 我添加了DataTable to a Container小部件 当我不向标题添加背景颜色时 它效果很好 执行此操作时 整个表格的颜色都会改变 Container decorat
  • Python:通过套接字发送的消息大小

    我正在尝试使用发送消息socket图书馆 由于消息的大小是可变的 因此我决定在字符串的开头附加消息的大小 然后发送它 例如 如果消息是 Hello World 这是 13 个字符长 我已经计算过 EOL 我会发送类似的内容 sizeof13
  • 如何区分线条的各个部分?

    我有两个文件想要比较 这些行有时间戳 可能还有一些我想在匹配算法中忽略的其他内容 但如果匹配算法发现文本的其余部分存在差异 我仍然希望输出这些项目 例如 1c1 lt junit4 2013 01 11 04 43 57 392 INFO
  • 如何从字符串中删除最后一个字符

    这可能是一个简单的任务 但我是 PHP 新手 我正在创建一串从数据库获取的值以用于特定目的 如何从字符串中删除最后一个字符 str foreach dataarray as value str value 它给了我类似的字符串ABC DEF
  • Jaas - 请求可更新的 Kerberos 票证

    我有一个 Java API 它与 Kerberos 服务器通信并执行各种操作 截至目前 我的 API 向 Kerberos 服务器请求不可更新的票证 据我了解 jaas 配置文件有一个选项可以将 renewTGT 选项设置为 true 以便
  • OpenCV (C++) - 设置像素的 HSV 值

    我有一个 RGB 图像 已转换为 HSV 我的目标是将每个不满足特定色调值 100 的像素设置为黑色 所以 H S V 0 我有这个代码 frame3是HSV Mat图像 色调 100 for int i 0 i
  • 计算字符串中的单词数

    我正在自学C 我编写了这个程序来计算字符串中的单词数 我知道这不是最好的方法 但这是我能想到的 我正在使用空格来计算单词数 问题就在这里 countWords ok x empty identifies it as an empty str
  • 如何在 Javascript 中迭代文件

    是否可以在 Javascript 中迭代文件集合 我正在编写一个 jQuery 插件 它要么接受图像数组 要么接受包含图像列表的目录 例如 任何一个 image1 jpg image2 jpg image3 jpg or http some
  • 如何在c中打印数组的最后一个元素

    我想检测 C 代码中整数数组的最后一个元素 否则 当数组元素为空时 我需要停止处理数组数据 实际上 我的数组有固定的最大大小 并且它是从外部文件填充的 所以我不知道它何时停止填充数组 最后一个元素就位 sizeof array sizeof
  • 如何合并同一数组内具有相同 id 的对象?

    我需要解析我的应用程序的 API 以获取此对象数组 parsedPlan id start small degressive rate 0 22 small hourly rate 2 large degressive rate 0 27
  • Java 泛型类型擦除:何时以及会发生什么?

    我读到了有关 Java 类型擦除的内容在甲骨文网站上 什么时候发生类型擦除 在编译时还是运行时 类什么时 候加载 类什么时 候实例化 很多网站 包括上面提到的官方教程 都说类型擦除发生在编译时 如果在编译时完全删除类型信息 那么当调用没有类