我有两个问题
1.以下两个声明之间是否有任何区别。?
(案例i)
List<String> li = new ArrayList();
(案例ii)
List<String> li = new ArrayList<String>();
2.我知道仿制药的好处是Stronger type checks at compile time
那么为什么我们需要在case ii
中声明?
由于对象创建在运行时仅在编译时声明。
答案 0 :(得分:8)
执行的代码没有区别 - 但第一个表单会生成警告。 如果您没有为泛型启用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()
)的表达式作为要赋值给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);
甚至:
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 generics FAQ。
答案 1 :(得分:2)
没有。菱形语法仅仅是编码/打字的简写。这两个是相同的
List<String> a = new ArrayList<String>();
List<String> a = new ArrayList<>();
对于编译过程,它们的处理方式相同,提示编译器。即使在类型擦除之前,它们也是一样的。这对你来说简直就是一种便利。
答案 2 :(得分:1)
两个声明是相同的:它们都是:
List<String>
这两个作业不同。
在运行时(由于类型擦除)它们也是相同的,但是在编译时你得到第一个警告,因为你正在为一个类型变量分配一个 raw 类型。 / p>