我有两个问题
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?
由于对象创建在运行时仅在编译时声明.
执行的代码没有区别- 但第一个表单将生成警告.如果您没有为泛型启用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泛型常见问题解答.