Java原始类型声明

时间:2017-07-21 07:22:02

标签: java generics compilation compiler-warnings

嗯,这个网站上有很多关于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<>();)中添加通用引用只会导致删除编译器警告。

我理解使用原始类型是一个坏习惯,但我的问题是将右侧作为原始类型编写的差异(编译警告除外)。

谢谢!

2 个答案:

答案 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

所以必须发出警告。