问题
List<String> list = new LinkedList();
在左侧,您使用的是泛型类型,而右侧则使用 原始类型 。Java 中的原始类型实际上只是为了与前泛型代码兼容而存在,除非您绝对需要,否则永远不应在新代码中使用。List<String>
LinkedList
现在,如果 Java 从一开始就有泛型,并且没有类型,例如 ,这些类型最初是在它具有泛型之前创建的,那么它可能已经做到了这一点,以便泛型类型的构造函数在可能的情况下自动从赋值的左侧推断其类型参数。但它没有,它必须区别对待原始类型和泛型类型,以实现向后兼容性。这使得他们需要制作一种略有不同但同样方便的方式来声明泛型对象的新实例,而不必重复其类型参数...钻石运营商。LinkedList
就的原始示例而言,编译器会为该赋值生成警告,因为它必须这样做。请考虑以下情况:List<String> list = new LinkedList()
List<String> strings = ... // some list that contains some strings
// Totally legal since you used the raw type and lost all type checking!
List<Integer> integers = new LinkedList(strings);
泛型的存在是为了提供编译时保护,防止做错事。在上面的示例中,使用原始类型意味着您无法获得此保护,并且将在运行时收到错误。这就是不应使用原始类型的原因。
// Not legal since the right side is actually generic!
List<Integer> integers = new LinkedList<>(strings);
但是,菱形运算符允许将赋值的右侧定义为具有与左侧相同的类型参数的真正通用实例。无需再次键入这些参数。它允许您以几乎与使用原始类型相同的努力来保持泛型的安全性。
我认为要理解的关键是原始类型(没有)不能与泛型类型一样对待。声明原始类型时,您不会获得泛型的任何好处和类型检查。您还必须记住,泛型是Java语言的通用部分...它们不仅适用于 s 的无参数构造函数!<>
Collection