类型擦除和类型推断有什么区别?它们都是编译时操作吗?
类型擦除:在编译时过程中删除通用类型信息。
Box<String>
被翻译为类型 Box
,称为原始类型。类型推断与类型擦除有何不同?
JDK 7 之前:
Box<String> box=new Box<String>();
从 JDK 7 开始:
Box<String> box=new Box<>();
我猜上面的例子是类型推断。是这样吗?
Type Inference
与Type Erasure
相反吗?
两者满足完全不同的需求:
类型擦除就像您所说的那样,并且是必需的,因为 java 字节代码不是通用的,因此您需要删除类型。这不是一个可以帮助您编码的功能,它只是 jvm 必须发生的自动编译时间更改才能理解您的代码。
另一方面,类型推断是编译器“智能”并且知道您所指的类型,即使您实际上没有编写它。就像在您的示例中一样,编译器知道
Box<>()
实际上意味着 Box<String>()
,并允许您继续使用类型安全进行编码,就像编写 Box<String>
一样。这样你就可以编写更少冗长的代码,并且编译器仍然可以理解它。
从这一切你可以了解到,Java 中的泛型实际上主要是一个编译时的东西,它可以让你更安全地编码,并帮助你在编译时而不是运行时发现错误。
它们都是编译时操作。
类型擦除是将通用 Java 源代码转换回常规 Java 代码(删除
T
、A
和任何其他参数化类型)。
当调用泛型方法或创建泛型类型对象时,可能会发生类型推断。例如,如果您
class Box<T> {
...
}
然后当你写的时候
Box<String> box = new Box<>();
// type parameter inferred
主要区别:
焦点:类型擦除涉及处理泛型代码时在编译时和运行时发生的情况,特别是如何删除类型信息。类型推断重点关注编译器如何根据上下文确定泛型类型。
目的:类型擦除主要是为了向后兼容并确保泛型代码可以与非泛型代码互操作。类型推断旨在提高代码可读性并减少对显式类型参数规范的需求。
Timing:类型擦除发生在编译过程中,并影响生成的字节码。类型推断是编译器的一项功能,可在编译过程中确定泛型类型。