当前位置: 首页 > 面试题库 >

为什么不从下一个JVM中删除类型擦除?

澹台蕴藉
2023-03-14
问题内容

Java在Java 5中引入了带有泛型的类型擦除,因此它们可以在Java的旧版本上使用。这是兼容性的折衷。从那以后,我们就失去了兼容性–字节码可以在JVM的更高版本上运行,但不能在较早的版本上运行。这似乎是最糟糕的选择:我们丢失了类型信息,并且仍然无法在较旧版本上运行针对较新版本JVM编译的字节码。发生了什么?

具体来说,我是在问是否存在任何技术原因,导致无法在下一版JVM中删除类型擦除(假设像以前的发行版一样,其字节码也将无法在上一版中运行)。

[3]:对于确实喜欢它的人,可以以类似于Retrolambda的方式向后移植类型擦除。

编辑:我认为对向后兼容性与向前兼容性的定义的讨论使这个问题变得晦涩。


问题答案:

在某种程度上,将来将通过项目valhalla删除擦除操作,以实现针对价值类型的专门实现。

或者更准确地说,类型擦除确实意味着不存在泛型的类型专门化,而valhalla将在基元上引入专门化。

具体来说,我在问是否有任何技术原因导致无法在下一版JVM中删除类型擦除

性能。您不必为泛型类型,实例或生成的类的所有组合生成专门的代码,而不必携带类型标签,多态内联html" target="_blank">缓存和运行时类型检查(由编译器生成的instanceof检查)保持简单,我们仍然可以通过编译时检查进行类型安全。

当然也有很多缺点,但是已经进行了权衡,还有一个问题是什么会促使JVM开发人员改变这种权衡。

而且这也可能是兼容性,可能有一些代码依靠依赖类型擦除来执行未经检查的强制转换以滥用泛型集合,如果强制执行类型约束,类型擦除会破坏类型集合。



 类似资料:
  • Java在Java5中引入了泛型的类型擦除,因此它们可以在Java的旧版本上工作。这是一个兼容性的折衷。从那以后,我们就失去了兼容性[1][2][3]--Bytecode可以在JVM的更高版本上运行,但不能在更早的版本上运行。这看起来可能是一个更糟糕的选择:我们丢失了类型信息,并且仍然无法在旧版本的JVM上运行为较新版本的JVM编译的字节码。怎么了? 具体地说,我想问的是,在JVM的下一个版本中为

  • 我正在编写C++来解决这个问题,从leetcode:https://leetcode.com/problems/remove-element/ 给定数组nums和值val,移除该值的所有实例并返回新的长度。 不要为另一个数组分配额外的空间,您必须用O(1)个额外内存修改输入数组。 元素的顺序可以更改。你在新长度之外留下什么并不重要。 您的函数应该返回长度=2,nums的前两个元素为2。 在返回长度

  • 我有一个这样定义的方法: 我的单元测试我错误地这样测试它: 这应该会产生编译时错误(当我尝试使用javac编译它时,它会产生编译时错误),但eclipse允许它编译。 我真的不明白为什么eclipse允许这段代码编译,有人能提供一些信息吗,为什么这会在eclipse中编译? eclipse版本是:面向Web开发人员的eclipse Java EE IDE。版本:Luna Service Relea

  • 问题内容: 我正在使用填充要在中列出的项目。一切正常。 但是现在我想保持项目列表的动态,即我希望能够在运行时从选择列表中添加/删除项目。但是,当我致电或时,我总是得到,即使该类的将这两种方法描述为可用于该预期目的也是如此。 这是一个错误,真的没有实现,还是我在这里遗漏了什么? 问题答案: 您可能使用普通的Java数组(例如,)初始化了适配器。尝试使用一些实现接口的东西(例如)。

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

  • 下面的代码没有在OpenjDK 11上编译。在我看来,B中的test1应该覆盖A中的test1,因为: 方法有相同的名称。 这些方法具有相同的参数列表。 这些方法具有相同的可见性。 这些方法实际上不会抛出可能不兼容的检查异常。 它们的返回类型是协变的。 我使用了一个反编译器,分别对每个类进行反编译。编译后的代码实际上像我期望的那样工作。它用数字代替U扩展数字,用整数代替T扩展整数,以此类推。但当我