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

时间:2012-03-19 16:13:46

标签: java generics java-7

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

  

错误:无法推断HashMap的类型参数;           map map2 = new HashMap<>(){     原因:不能使用'<>'与匿名内部类     其中K,V是类型变量:       K扩展了在HashMap类中声明的Object       V扩展在HashMap类中声明的Object

代码:

    Map<String, String> map1 = new HashMap<String, String>() { //compiles fine

        {
            put("abc", "abc");
        }
    };

    Map<String, String> map2 = new HashMap<>() { //does not compile

        {
            put("abc", "abc");
        }
    };

修改
谢谢你的回答 - 我应该更好地阅读编译错误。 我在JLS

中找到了这个项目
  

如果类实例创建表达式使用“&lt;&gt;”声明匿名类,则是编译时错误类的类型参数的形式。

4 个答案:

答案 0 :(得分:6)

此处没有静态初始值设定项(关键字 static 完全丢失)。

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

由于您将获得HashMap的匿名子类,因此菱形运算符在此处不起作用,因为子类将被编译为就像您编写... extends HashMap<Object, Object>一样,这显然与Map<String, String>

答案 1 :(得分:4)

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

试试这个:

Map<String, String> map1 = new HashMap<>();

{
    map1.put("abc", "abc");
}

答案 2 :(得分:3)

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

致电Allowing the diamond syntax with some anonymous class constructors

Link.

答案 3 :(得分:1)

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

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