首先:除非您使用 Java 7,否则所有这些都不起作用,因为菱形<>
仅在该 Java 版本中引入。
此外,此答案假设读者了解泛型的基础知识。如果您不这样做,请阅读本教程的其他部分,并在您理解这些部分后回来。
当编译器可以自己找出类型时,菱形实际上是不必重复泛型类型信息的捷径。
最常见的用例是当变量在其初始化的同一行中定义时:
List<String> list = new ArrayList<>(); // is a shortcut for
List<String> list = new ArrayList<String>();
在这个例子中,区别并不大,但是一旦你得到Map<String, ThreadLocal<Collection<Map<String,String>>>>
它,它将是一个重大的改进(注意:我不鼓励实际使用这样的结构!)。
问题是规则只能走那么远。在上面的示例中,应该使用什么类型非常明显,编译器和开发人员都同意。
在这条线上:
list.addAll(new ArrayList<>());
这似乎很明显。至少开发人员知道类型应该是String
.
但是,查看 的定义,Collection.addAll()
我们看到参数类型是Collection<? extends E>
.
这意味着addAll
接受任何包含任何未知类型的对象的集合,这些对象扩展了我们的list
. 这很好,因为这意味着你可以addAll
aList<Integer>
到 a List<Number>
,但它使我们的类型推断更加棘手。
事实上,它使类型推断在 JLS 当前制定的规则中不起作用。在某些情况下,可以争辩说这些规则可以扩展到工作,但当前的规则暗示不这样做。