我想知道为什么第二个映射声明(使用菱形运算符)没有编译,而第一个却编译了。编译错误:
错误:无法推断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");
}
};