我的印象是,在 Java 中,由于类型擦除,
instanceof
运算符不能与泛型一起使用。但是,下面的代码片段中的第一个条件语句编译并运行时没有任何错误。谁能解释为什么第一个条件不会导致编译时错误?我正在将 IntelliJ IDEA 与 Oracle JDK 17 一起使用。
public class InstanceofTest {
public static class Tea {}
public static class Herb {}
// Why is this working?
public static void main(String[] args) {
List<Tea> teas = new ArrayList<>();
if (teas instanceof List<Tea>) {
System.out.println("TRUE");
} else {
System.out.println("FALSE");
}
// Compile error
// if (teas instanceof List<Herb>) {
// System.out.println("TRUE");
// } else {
// System.out.println("FALSE");
// }
}
}
在 Java 中,当代码运行时,像
List<Tea>
这样的泛型会简化为 List
,这就是为什么你通常不能将 instanceof
与泛型类型一起使用。 instanceof List<Tea>
起作用的原因是,在编译时,Java 编译器仅检查 List
的 List<Tea>
部分。由于类型擦除,它不关心 <Tea>
部分,但它不会抛出错误,因为这样写并不是“错误”,因为语法本身并没有不正确。编译器知道您正在处理上下文中的 List<Tea>
,因此它不会反对。另一方面,当您尝试 instanceof List<Herb>
时,编译器会介入,因为它知道您的列表不能是
List<Herb>
,因为您告诉它是
List<Tea>
。这会根据您提供的信息在编译时发生,无论运行时列表的实际内容如何。TL;博士:
由于类型擦除,Java 编译器根据编译时可用的信息做出决策,而不是运行时列表的实际内容。