List<String> list = new ArrayList();
将导致编译器警告。
但是,以下示例在编译时没有任何警告: List<String> list = new ArrayList<>();
我很好奇为什么根本需要引进钻石操作员。如果不存在类型参数,为什么不对构造函数进行类型推断(因为它已经在Java中的静态方法中完成,并被Google
guava等集合库所利用)
编辑
:使用millimoose答案作为起点,我了解了实际上是什么类型的擦除,而不仅仅是删除所有类型的信息。编译器实际上做了更多(从官方文档复制):
最终的答案必须来自设计该功能的人员,但是我认为这是将其与使用原始类型区分开来的原因,原始类型使编译器出于兼容性的目的而完全不同。带有原始类型的表达式的处理与涉及泛型的表达式的处理有
微妙的
区别,因此在此SO问题中找到了一个示例:泛型搞乱了不相关的集合
问题内容: 在Java 1.7.0_55中,如果我编写此字段声明,则会收到编译错误(“不兼容的类型”): 如果我将其改为: 它编译良好。(我在这里以syncedMap为例,但其他Collections方法,不可修改,同步等也是如此) 但是,为什么钻石操作员不能像我在这里期望的那样工作?由于Collections.synchronizedMap()声明为: 在我看来,构造函数调用的类型参数必须与字段
问题内容: 我读到从Java 7开始,像在第一条语句中那样在右侧指定类型来创建Collections是不好的样式,因为编译器可以从左侧推断类型。 我的问题是,当像这样初始化列表时,编译器找不到类型,并且我收到未经检查的类型警告: 问题答案: 编译器不会 推断 类型,因为您正在实例化 raw 。但是它足够聪明,可以警告您在使用此(原始)对象时可能会出现问题。 值得一提的是此警告背后的原因。由于类型擦
问题内容: 在Java 7和更高版本中,菱形通常可以像这样毫无问题地用于推断类型: 但是,它不能用于这样的匿名内部类: 为什么是这样?从逻辑上讲,在这种情况下,我绝对可以将类型推断为。做出该决定的逻辑上的理由是,实际上不能在匿名内部类上推断类型,还是出于其他原因而将其省略了? 问题答案: 在JSR-334中: 不支持将Diamond与匿名内部类一起使用,因为这样做通常需要扩展类文件签名属性以表示不
问题内容: 考虑下面的Java代码,它尝试实例化一些: 并且很简单;在Java 7中使用新的Diamond运算符来减少不必要的类型参数重复。 是使用匿名类的一种变体,可能会覆盖的某些方法。 尝试使用菱形运算符,类似于,但这是编译错误,消息 “ <>”不能与匿名类一起使用。 产生一个错误,证明编译器知道实际需要的类型。错误消息是 类型不匹配:无法从新的ArrayList (){}转换为List 因此
如何将Java7类型推断用于泛型实例创建功能?使用这种新样式有什么好处?