使用菱形运算符的双大括号初始化(匿名内部类)



我想知道为什么第二个映射声明(使用菱形运算符)没有编译,而第一个却编译了。编译错误:

错误:无法推断HashMap的类型参数;Map map2=新的HashMap<>(){原因:无法使用'<>'具有匿名内部类其中K、V是类型变量:K扩展类HashMap中声明的ObjectV扩展类HashMap 中声明的对象

代码:

    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 中发现了夸大

如果类实例创建表达式使用类的类型参数的"<>"形式声明匿名类,则是编译时错误。

此处没有static初始值设定项(完全缺少关键字tatic)。

基本上,您创建了HashMap的一个新的匿名子类,并在此处定义实例初始化程序块。顺便说一句,这只是因为HashMap不是最终版本。

由于您将获得HashMap的一个匿名子类,菱形运算符在这里不起作用,因为子类的编译方式就像您编写... extends HashMap<Object, Object>一样,而这显然与Map<String, String>不兼容。

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

试试这个:

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

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

它叫Allowing the diamond syntax with some anonymous class constructors

链接。

请注意,也可以完全省略菱形。然而,在编译时,这只是因为它忽略了Java泛型,并依赖于Java与以前版本向后兼容的事实。

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

最新更新