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

时间:2013-07-27 06:17:33

标签: java generics

我有两个问题

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

List<String> li = new ArrayList();  

(案例ii)

List<String> li = new ArrayList<String>();  

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

3 个答案:

答案 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>