当前位置: 首页 > 面试题库 >

为什么Diamond运算符不适用于Java 7中的java.util.Collections方法?

秦涵涤
2023-03-14
问题内容

在Java 1.7.0_55中,如果我编写此字段声明,则会收到编译错误(“不兼容的类型”):

   private final Map<String,Object> myMap =
       Collections.synchronizedMap(new HashMap<>());

如果我将其改为:

   private final Map<String,Object> myMap =
       Collections.synchronizedMap(new HashMap<String,Object>());

它编译良好。(我在这里以syncedMap为例,但其他Collections方法,不可修改,同步等也是如此)

但是,为什么钻石操作员不能像我在这里期望的那样工作?由于Collections.synchronizedMap()声明为:

public static <K,V> Map<K,V> synchronizedMap(Map<K,V> m) {

在我看来,构造函数调用的类型参数必须与字段声明的类型参数相同,并且编译器应该能够基于此推断构造的类类型参数

我尝试在JLS中寻找一个子句,该子句说这种语法是不可接受的,但是找不到。谁能指出我的意思?


问题答案:

这会因Java 7中的编译器错误而失败,但会在Java 8中成功编译。简而言之,编译器的类型推断未捕获Java
7中正确的推断类型,但更好的类型推断会推断Java 8中的正确类型。

此更改是针对Java 8的JEP(JDK增强建议)101。

摘要

平滑地扩展方法类型推断的范围,以支持(i)方法上下文中的推断和(ii)链式调用中的推断。

Java 8能够通过带有参数和方法调用链的多个方法调用来推断类型。现在,它可以从分配的左侧<String, Object>通过调用Collections.synchronizedMap的参数中的菱形运算符来确定new HashMap<>()



 类似资料:
  • 问题内容: 将导致编译器警告。 但是,以下示例在编译时没有任何警告: 我很好奇为什么根本需要引进钻石操作员。如果不存在类型参数,为什么不对构造函数进行类型推断(因为它已经在Java中的静态方法中完成,并被Google guava等集合库所利用) 编辑 :使用millimoose答案作为起点,我了解了实际上是什么类型的擦除,而不仅仅是删除所有类型的信息。编译器实际上做了更多(从官方文档复制): 如果

  • 问题内容: 我正在尝试使用Diamond运算符,但是却收到以下消息: -source 1.5中不支持Diamond运算符(使用-source 7或更高版本来启用Diamond运算符) 它可以在Android的netbeans中修复吗? 问题答案: Android需要Java来源合规性5.0或6.0(Java5 / 6)。开箱即用不支持Java7。这些文章描述了有关如何使用某些Java7功能的技巧:

  • 问题内容: um(使用Java 7(1.7.0_67))并将项目语言级别设置为7-钻石,ARM,多捕获。我的代码如下,使用maven进行构建时会引发编译错误的行。 InstrumentingAgent第63行中的多捕获块 编译时出现以下错误。为什么不起作用?我究竟做错了什么。我正在使用IntelliJ IDE。 根据我所读的内容,钻石算子应该与Java 7一起使用。但是为什么我要使用它。如果我用相

  • 问题内容: 考虑下面的Java代码,它尝试实例化一些: 并且很简单;在Java 7中使用新的Diamond运算符来减少不必要的类型参数重复。 是使用匿名类的一种变体,可能会覆盖的某些方法。 尝试使用菱形运算符,类似于,但这是编译错误,消息 “ <>”不能与匿名类一起使用。 产生一个错误,证明编译器知道实际需要的类型。错误消息是 类型不匹配:无法从新的ArrayList (){}转换为List 因此

  • 问题内容: 我注意到我可以使用运算符比较所有本机数据类型(整数,字符串,布尔值,浮点数等),还可以比较包含本机数据类型的列表,元组,集合和字典。在这些情况下,操作员将检查两个对象是否相等。但是在某些其他情况下(试图比较我创建的类的实例),该运算符只是检查两个变量是否引用同一对象(因此在这些情况下,该运算符等效于该运算符) 我的问题是:什么时候操作员不只是比较身份? 编辑:我正在使用Python 3