这些通用类型之间有什么区别

Pra*_*ker 3 java generics

我有两个问题

1.以下两个声明之间是否有任何区别?
(案例i)

List<String> li = new ArrayList();  
Run Code Online (Sandbox Code Playgroud)

(案例ii)

List<String> li = new ArrayList<String>();  
Run Code Online (Sandbox Code Playgroud)

我知道仿制药的好处是Stronger type checks at compile time.
那为什么我们需要声明像 case ii
由于对象创建在运行时仅在编译时声明.

Jon*_*eet 8

执行的代码没有区别- 但第一个表单将生成警告.如果您没有为泛型启用linting,则可能会收到如下消息:

Note: Test.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
Run Code Online (Sandbox Code Playgroud)

使用建议的标志,你会得到这样的东西:

Test.java:6: warning: [unchecked] unchecked conversion
        List<String> li = new ArrayList();
                          ^
  required: List<String>
  found:    ArrayList
1 warning
Run Code Online (Sandbox Code Playgroud)

警告的原因是它有点不安全 - 您使用原始类型(new ArrayList())的表达式作为要分配给类型变量的值List<String>.编译器不知道此原始类型值是否实际上是为了保存其他vau 而最初创建的.例如:

List numbers = new ArrayList(); // Raw types on both sides
numbers.add(Integer.valueOf(10));
List<String> li = numbers;
String first = li.get(0);
Run Code Online (Sandbox Code Playgroud)

甚至:

List<Integer> numbers = new ArrayList<Numbers>();
numbers.add(Integer.valueOf(10));
List raw = numbers;
List<String> li = raw;
String first = li.get(0);
Run Code Online (Sandbox Code Playgroud)

在这两种情况下,当我们到达最后一行时,我们最终会遇到异常...而如果我们对所有表达式使用泛型类型,它甚至不会编译:

List<Integer> numbers = new ArrayList<Numbers>();
numbers.add(Integer.valueOf(10));
List<String> li = numbers; // Compile-time error
String first = li.get(0);
Run Code Online (Sandbox Code Playgroud)

原始类型仅用于向后兼容,应尽可能避免.

有关更多详细信息,请参阅Java泛型常见问题解答.