简体   繁体   English

为什么在运行时需要 java 类型擦除?

[英]Why java type erasure is needed at runtime at all?

Below is an excerpt from java documentation here以下是java 文档的摘录

Because of type erasure, List<Number> and List<String> both become List.由于类型擦除, List<Number>List<String>都变成了 List。 Consequently, the compiler allows the assignment of the object l, which has a raw type of List, to the object ls.因此,编译器允许将具有 List 原始类型的 object l 分配给 object ls。

Also from the same documentation也来自相同的文档

Consider the following example:考虑以下示例:

List l = new ArrayList<Number>();
List<String> ls = l;       // unchecked warning
l.add(0, new Integer(42)); // another unchecked warning
String s = ls.get(0);      // ClassCastException is thrown

During type erasure, the types ArrayList and List become ArrayList and List, respectively.在类型擦除期间,类型 ArrayList 和 List 分别变为 ArrayList 和 List。

Why compiler can't show this as an error (instead of warning).为什么编译器不能将此显示为错误(而不是警告)。 Could someone kindly help with an example where warning is needed and will cause an issue (or make certain useful patterns impossible) when warning becomes an error.有人可以帮忙举一个需要警告的例子,当警告变成错误时会导致问题(或使某些有用的模式成为不可能)。

Java gained type variables in java 1.5. Java 在 java 1.5 中获得了类型变量。 Before java 1.5, they did not exist .在 java 1.5 之前,它们不存在

Java also strongly dislikes releasing new versions such that 'upgrading' is more involved than just 'simply compile your existing code with the new compiler and it all just works exactly like it did before'. Java 也非常不喜欢发布新版本,这样“升级”就比“简单地用新编译器编译现有代码,它的工作方式与以前完全一样”更多。 Also, 'you can run code compiled with the javac from java 1.4, on the java.exe from 1.5 and it runs fine'.此外,“您可以在 1.5 的java.exe上运行使用 java 1.4 的javac编译的代码,并且运行良好”。

Why?为什么? Well, because otherwise you get a split community, and because most projects use 500 dependencies, that is hugely detrimental.好吧,因为否则你会得到一个分裂的社区,而且因为大多数项目使用 500 个依赖项,这是非常有害的。 You can't 'upgrade' from java 1.4 to 1.5 until each and every single last one of those 500 deps has upgraded.你不能从 java 1.4“升级”到 1.5,直到这 500 个 deps 中的每一个都升级。

Combine these 2 facts and generics makes sense:结合这两个事实,generics 是有道理的:

  • Why erasure at all?为什么要完全擦除? Because how else could it work?因为它还能如何工作? Class files stemming from javac1.4 cannot possibly have the generics info, given that they did not exist when javac1.4 was released源自 javac1.4 的 Class 文件不可能有 generics 信息,因为它们在 javac1.4 发布时不存在

  • Why 'raw types'?为什么是“原始类型”? Because pre-generics code by their nature have them ( List<T> would be a compiler error on java 1.4), and by their nature, there is no sanity, typevar-wise.因为预泛型代码本质上具有它们( List<T>将是 java 1.4 上的编译器错误),并且就其本质而言,没有理智,类型变量明智。 You could write this:你可以这样写:

List foo = new ArrayList();
foo.add(5);
foo.add("hello");

and it compiles just fine on javac 1.4.它在 javac 1.4 上编译得很好。 Therefore it MUST also compile on javac 1.5 .因此它也必须在 javac 1.5 上编译 As a compromise, if you attempt to compile that on javac from 1.5, it works and produces a class file that acts identically, but you do get warnings.作为一种折衷方案,如果您尝试在 javac 上从 1.5 编译它,它会工作并生成一个行为相同的 class 文件,但您确实会收到警告。

java 1.5 is now 25 years old or whatnot. java 1.5 现在已经 25 岁了。 So it all seems weird and archaic now.所以现在这一切看起来都很奇怪和过时。 But you're asking 'why'.但你在问“为什么”。 This is why.这就是为什么。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM