我有两个问题
1.下面两个声明有什么区别吗?
(案例一)
List<String> li = new ArrayList();
(案例二)
List<String> li = new ArrayList<String>();
2.我知道仿制药的好处是Stronger type checks at compile time
。
那为什么我们需要声明 like in case ii
呢?
由于对象创建是在运行时仅在编译时声明。
执行的代码没有区别——但第一种形式会产生警告。如果您没有为泛型启用 linting,您可能会收到如下消息:
Note: Test.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
使用建议的标志,您将获得如下信息:
Test.java:6: warning: [unchecked] unchecked conversion
List<String> li = new ArrayList();
^
required: List<String>
found: ArrayList
1 warning
警告的原因是它有点不安全 - 您使用原始类型( new ArrayList()
) 的表达式作为分配给 type 变量的值List<String>
。编译器不知道这个原始类型值是否实际上最初是为了保存其他值而创建的。例如:
List numbers = new ArrayList(); // Raw types on both sides
numbers.add(Integer.valueOf(10));
List<String> li = numbers;
String first = li.get(0);
甚至:
List<Integer> numbers = new ArrayList<Numbers>();
numbers.add(Integer.valueOf(10));
List raw = numbers;
List<String> li = raw;
String first = li.get(0);
在这两种情况下,当我们到达最后一行时,我们都会得到一个异常......而如果我们对所有表达式都使用泛型类型,它甚至不会编译:
List<Integer> numbers = new ArrayList<Numbers>();
numbers.add(Integer.valueOf(10));
List<String> li = numbers; // Compile-time error
String first = li.get(0);
原始类型仅用于向后兼容,应尽可能避免使用。
有关更多详细信息,请参阅Java 泛型常见问题解答。
不,菱形语法只是编码/打字的简写。这两个是一样的
List<String> a = new ArrayList<String>();
List<String> a = new ArrayList<>();
它们在编译过程中被视为相同,对编译器的提示。即使在类型擦除之前,它们的处理方式也是一样的。这实际上只是为您提供便利。
这两个声明是相同的:它们都是:
List<String>
这是两个不同的任务。
在运行时(由于类型擦除)它们也是相同的,但在编译时您会收到第一个警告,因为您将原始类型分配给类型化变量。