Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/360.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么菱形操作符不适用于java 7中的java.util.Collections方法?_Java_Generics_Diamond Operator - Fatal编程技术网

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

为什么菱形操作符不适用于java 7中的java.util.Collections方法?,java,generics,diamond-operator,Java,Generics,Diamond Operator,在Java 1.7.0_55中,如果我编写此字段声明,则会出现编译错误(“不兼容类型”): private final Map myMap= Collections.synchronizedMap(新的HashMap()); 如果我将其改为: private final Map<String,Object> myMap = Collections.synchronizedMap(new HashMap<String,Object>()); priv

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

private final Map myMap=
Collections.synchronizedMap(新的HashMap());
如果我将其改为:

   private final Map<String,Object> myMap =
       Collections.synchronizedMap(new HashMap<String,Object>());
private final Map myMap=
Collections.synchronizedMap(新的HashMap());
它编译得很好。(我在这里使用synchronizedMap作为示例,但对于其他集合方法(不可修改*、synchronized*等)也是如此)

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

public static <K,V> Map<K,V> synchronizedMap(Map<K,V> m) {
公共静态映射同步映射(映射m){
在我看来,构造函数调用的类型参数必须与字段声明的类型参数相同,编译器应该能够基于此推断构造的类类型参数


我试图在JLS中查找一个子句,该子句表示此语法不可接受,但我找不到。有人能给我指一下吗?

这是因为您试图将
新HashMap()
传递给
集合的方法
类。这与执行以下操作不同:

Map <String, Integer> map = new HashMap<>();
Map Map=newhashmap();

您正在使用的方法需要已知类型的映射。菱形语法只是声明和初始化泛型类的标准语法的一种补充

public static <K,V> Map<K,V> synchronizedMap(Map<K,V> m) {
V由myString确定

当你给予

new HashMap<>()
newhashmap()
那么就没有泛型了,所以编译器会猜测您:

new HashMap<Object, Object>()
newhashmap()
所以你得到了

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

这就是和不兼容类型错误。

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

这一变化是不公平的

摘要

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


Java 8能够通过带有参数和方法调用链接的多个方法调用来推断类型。现在,它可以从赋值的左侧通过调用
集合来确定类型。synchronizedMap
到该调用的参数中的菱形操作符,
new HashMap()

您只是Java 7糟糕的类型推断的受害者。
new HashMap<>()
new HashMap<Object, Object>()
private final Map<String,Object> myMap =
   Collections.synchronizedMap(new HashMap<Object,Object>());