Java 7中的菱形运算符容许以下代码: 安全
List<String> list = new LinkedList<>();
可是,在Java 5/6中,我能够简单地编写: ide
List<String> list = new LinkedList();
我对类型擦除的理解是这些彻底相同。 (不管如何,泛型都会在运行时删除)。 函数
为何要打扰钻石呢? 它容许哪些新功能/类型安全? 若是它没有产生任何新功能,为何他们将其称为功能? 我对这个概念的理解有缺陷吗? spa
此行致使[unchecked]警告: code
List<String> list = new LinkedList();
所以,问题发生了变化:为何仅在建立新集合时才自动取消[unchecked]警告? 对象
我认为,而后添加<>
功能会更加困难。 开发
UPD :我还认为,若是合法地使用原始类型“仅用于几件事”会形成混乱。 编译器
您的理解有些瑕疵。 Diamond运算符是一个不错的功能,由于您没必要重复本身的操做。 在声明类型时一次定义类型是有意义的,可是在右侧再次定义它是没有意义的。 DRY原理。 string
如今来解释有关定义类型的全部模糊性。 您是对的,该类型在运行时已删除,可是一旦您想从具备类型定义的列表中检索某些内容,就能够在声明该列表时将其恢复为您定义的类型,不然它将丢失全部特定功能而且仅具备对象功能,除非您将检索到的对象转换为原始类型,不然有时会很是棘手,并致使ClassCastException。 io
使用List<String> list = new LinkedList()
将得到原始类型警告。
当您写List<String> list = new LinkedList();
,编译器会产生“未经检查”的警告。 您可能会忽略它,可是若是您过去曾经忽略这些警告,则可能还会错过一条警告消息,该警告通知您有关实型安全问题。
所以,最好编写一个不会生成额外警告的代码,而且菱形运算符容许您以便捷的方式进行操做,而无需没必要要的重复。
Diamond运算符的目的只是在声明泛型类型时减小代码的类型。 它对运行时没有任何影响。
若是您在Java 5和6中指定,则惟一的区别是
List<String> list = new ArrayList();
是您必须在list
指定@SuppressWarnings("unchecked")
(不然,您将得到未选中的强制转换警告)。 个人理解是,钻石运营商正在努力使开发变得更容易。 与泛型的运行时执行彻底无关。
与问题
List<String> list = new LinkedList();
是在左侧,您使用的是通用类型List<String>
,而在右侧,您使用的是原始类型LinkedList
。 Java中的原始类型实际上仅存在于与前泛型代码的兼容性,而且除非绝对必要,不然绝对不能在新代码中使用。
如今,若是Java从一开始就具备泛型,而且没有诸如LinkedList
类的类型,而该类型最初是在具备泛型以前建立的,则它可能已经作到了,这样泛型类型的构造函数会自动从Java推断其类型参数。若是可能的话,在做业的左侧。 但事实并不是如此,为了向后兼容,必须对原始类型和泛型类型进行不一样的处理。 这使得他们须要采起一种稍微不一样但一样方便的方式来声明泛型对象的新实例,而没必要重复其类型参数……菱形运算符。
就您的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语言的通用组成部分 ……它们不只仅适用于Collection
的no-arg构造函数!