带有钻石操作符的双括号初始化(匿名内部类)

我想知道为什么第二个地图声明(使用菱形运算符)在第一个地图声明时不会编译。 编译错误:

错误:无法推断HashMap的类型参数; Map map2 = new HashMap (){reason:不能使用带有匿名内部类的”,其中K,V是类型变量:K扩展在类HashMap中声明的对象V扩展在类HashMap中声明的Object

码:

Map map1 = new HashMap() { //compiles fine { put("abc", "abc"); } }; Map map2 = new HashMap() { //does not compile { put("abc", "abc"); } }; 

编辑
感谢您的回答 – 我应该更好地阅读编译错误。 我在JLS找到了这个项目

如果类实例创建表达式使用类的“”形式为类的类型参数声明一个匿名类,那么这是一个编译时错误。

这里没有静态初始化程序(关键字static完全丢失)。

基本上,您创建了一个新的HashMap匿名子类,并在此处定义实例intializer块。 顺便说一句,这只能起作用,因为HashMap不是最终的。

由于你将获得一个HashMap的匿名子类,菱形运算符在这里不起作用,因为子类将被编译,就像你写的那样... extends HashMap ,这显然与Map不兼容Map

钻石推理不适用于实例化匿名类,这就是你在这里所做的。

尝试这个:

 Map map1 = new HashMap<>(); { map1.put("abc", "abc"); } 

此function是Project Coin 2的一部分,将于2016年9月22日在Java 9中提供。

它的调用Allowing the diamond syntax with some anonymous class constructors

链接。

请注意,您可以完全省略钻石。 然而,虽然这是编译,但这只是因为它忽略了Javagenerics并且倾向于Java向后兼容以前的版本。

 Map map1 = new HashMap() { //compiles fine { put("abc", "abc"); } };