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
所以警告是必要的。
嗯,这个站点上有很多关于 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
所以警告是必要的。