Java 原始类型声明

Java raw type declaration

嗯,这个站点上有很多关于 Java 中原始类型和泛型的问题。甚至问下一行代码为什么会出现警告:

List<String> list = new ArrayList();

并且回答了很多次,因为 ArrayList() 是原始类型,所以编译器会发出警告,因为现在 list 不是 "type safe",写这行代码的选项是仅用于向后兼容。

我不明白,也没有找到关于它的问题,是为什么?由于编译器仅在静态引用上通过 "looking" 编译 Java 代码,因此编写 new ArrayList(); 而不是 new ArrayList<>();.[=17 的编译时间为何存在差异=]

例如写这段代码:

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,其中构造函数参数取决于类型参数:

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

所以警告是必要的。