嗯,这个网站上有很多关于Java中的原始类型和泛型的问题。甚至关于为什么下一行代码会出现警告的问题:
List<String> list = new ArrayList();
并且回答了很多次,因为 ArrayList(( 是原始类型,因此编译器会发出警告,因为现在list
不是"类型安全的",编写这行代码的选项只是为了向后兼容。
我不明白,也没有找到关于它的问题,是为什么?既然编译器通过仅"查看"静态引用来编译 Java 代码,那么编写new ArrayList();
而不是new ArrayList<>();
的编译时间为什么会有差异。
例如,编写以下代码:
List<String> list = new ArrayList(); // 1
list.add("A string"); // 2
list.add(new Object()); // 3
导致第 1 行出现编译警告,第 2 行没有编译问题,但第 3 行出现编译错误 - 类型安全。
因此 - 添加对第一行 (new ArrayList<>();
( 的泛型引用,只会导致删除编译器警告。
我知道使用原始类型是一个坏习惯,但我的问题实际上是将右侧编写为原始类型有什么区别(编译警告除外(。
谢谢!
编译器不关心创建变量list
引用的对象时使用的机制。事实上,它也可以指null
.或者它可以是对方法的调用。例:
void yourMethod() {
List<String> list = createStringList();
...
}
List<String> createStringList() {
return new ArrayList(); // raw type here
}
当具有正确的类型化变量(未使用原始类型声明(时,将根据泛型类型检查此变量的所有用法。
另一件事是,如果你的变量本身是用原始类型声明的:示例:
List list = new ArrayList();
list.add("A string");
list.add(new Object());
这编译得很好,但警告应该提醒您,因为稍后可能会中断!
假设您有另一个类,其中构造函数参数依赖于类型参数:
class Foo<T> {
Foo(T obj) { }
}
然后,编译器会在使用类型参数或菱形运算符创建参数类型时检查参数类型:
Foo<String> bar = new Foo<>(42); // doesn't compile
但是原始类型会关闭泛型检查:
Foo<String> bar = new Foo(42); // does compile but causes heap pollution
所以警告是必要的。