嗯,这个网站上有很多关于Java中原始类型和泛型的问题。甚至有关为什么下一行代码会出现警告的问题:
List<String> list = new ArrayList();
并且多次回答,因为ArrayList()是原始类型,因此编译器会发出警告,因为现在list
不是&#34;类型安全&#34;,并且写入此行的选项代码仅用于向后兼容。
我不明白,并且没有找到有关它的问题,这是为什么?由于编译器通过&#34;查找&#34;编译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<>();
)中添加通用引用只会导致删除编译器警告。
我理解使用原始类型是一个坏习惯,但我的问题是将右侧作为原始类型编写的差异(编译警告除外)。
谢谢!
答案 0 :(得分:2)
编译器不关心什么机制创建了变量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());
这个编译很好,但是警告应该提醒你,因为事情可能会在以后破坏!
答案 1 :(得分:1)
假设您有另一个类,其中构造函数参数取决于类型参数:
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
所以必须发出警告。