Java 中泛型中的擦除概念是什么?

2022-08-31 07:31:55

Java 中泛型中的擦除概念是什么?


答案 1

这基本上是泛型通过编译器技巧在Java中实现的方式。编译的泛型代码实际上只使用你谈论的任何地方(或其他一些类型参数) - 并且有一些元数据可以告诉编译器它确实是一个泛型类型。java.lang.ObjectT

当你针对泛型类型或方法编译一些代码时,编译器会计算出你的真正含义(即类型参数是什么),并在编译时验证你正在做正确的事情,但发出的代码再次只是在必要时生成额外的强制转换。在执行时,a 和 a 完全相同;额外的类型信息已被编译器擦除Tjava.lang.ObjectList<String>List<Date>

与此进行比较,例如,C#,其中信息在执行时保留,允许代码包含表达式,例如哪个等价于 - 除了后者无效。(请注意,.NET 泛型和 Java 泛型之间还有进一步的区别。类型擦除是处理 Java 泛型时许多“奇怪”警告/错误消息的来源。typeof(T)T.class

其他资源:


答案 2

作为旁注,这是一个有趣的练习,实际了解编译器在执行擦除时正在做什么 - 使整个概念更容易掌握。有一个特殊标志,您可以传递编译器以输出已擦除泛型并插入强制转换的java文件。例如:

javac -XD-printflat -d output_dir SomeFile.java

是传递给生成文件的编译器的标志。(这部分是告诉将它交给实际进行编译的可执行jar,而不仅仅是,但我离题了...)这是必要的,因为编译器需要一些地方来放置新的.java文件。-printflat-XDjavacjavac-d output_dir

当然,这不仅仅是擦除;编译器所做的所有自动操作都在这里完成。例如,还插入了默认构造函数,将新的 foreach 样式循环扩展到常规循环等。很高兴看到自动发生的小事情。forfor


推荐