Java 中泛型中的擦除概念是什么?
Java 中泛型中的擦除概念是什么?
这基本上是泛型通过编译器技巧在Java中实现的方式。编译的泛型代码实际上只使用你谈论的任何地方(或其他一些类型参数) - 并且有一些元数据可以告诉编译器它确实是一个泛型类型。java.lang.Object
T
当你针对泛型类型或方法编译一些代码时,编译器会计算出你的真正含义(即类型参数是什么),并在编译时验证你正在做正确的事情,但发出的代码再次只是在必要时生成额外的强制转换。在执行时,a 和 a 完全相同;额外的类型信息已被编译器擦除。T
java.lang.Object
List<String>
List<Date>
与此进行比较,例如,C#,其中信息在执行时保留,允许代码包含表达式,例如哪个等价于 - 除了后者无效。(请注意,.NET 泛型和 Java 泛型之间还有进一步的区别。类型擦除是处理 Java 泛型时许多“奇怪”警告/错误消息的来源。typeof(T)
T.class
其他资源:
作为旁注,这是一个有趣的练习,实际了解编译器在执行擦除时正在做什么 - 使整个概念更容易掌握。有一个特殊标志,您可以传递编译器以输出已擦除泛型并插入强制转换的java文件。例如:
javac -XD-printflat -d output_dir SomeFile.java
是传递给生成文件的编译器的标志。(这部分是告诉将它交给实际进行编译的可执行jar,而不仅仅是,但我离题了...)这是必要的,因为编译器需要一些地方来放置新的.java文件。-printflat
-XD
javac
javac
-d output_dir
当然,这不仅仅是擦除;编译器所做的所有自动操作都在这里完成。例如,还插入了默认构造函数,将新的 foreach 样式循环扩展到常规循环等。很高兴看到自动发生的小事情。for
for