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

Sim*_*ane 10 java generics diamond-operator

在Java 1.7.0_55中,如果我写这个字段声明,我得到一个编译错误("不兼容的类型"):

   private final Map<String,Object> myMap =
       Collections.synchronizedMap(new HashMap<>());
Run Code Online (Sandbox Code Playgroud)

如果我把它改为:

   private final Map<String,Object> myMap =
       Collections.synchronizedMap(new HashMap<String,Object>());
Run Code Online (Sandbox Code Playgroud)

它汇编很好.(我在这里使用synchronizedMap作为示例,但对于其他集合方法也是如此,不可修改*,同步*等)

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

public static <K,V> Map<K,V> synchronizedMap(Map<K,V> m) {
Run Code Online (Sandbox Code Playgroud)

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

我试图在JLS中寻找一个条款,说这种语法是不可接受的,但我找不到一个.有人能指点我吗?

rge*_*man 10

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

此更改是Java 8的JEP(JDK Enhancement Proposal)101.

摘要

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

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