当我尝试像下面这样创建对象时:
Map<Integer, Map<String, Integer>> myMap = new HashMap<Integer, HashMap<String, Integer>>();
语法上哪里出了问题,有人能解释一下吗?
Map<Integer, Map<String, Integer>> myMap = new HashMap<Integer, HashMap<String, Integer>>();
语法上哪里出了问题,有人能解释一下吗?
泛型不是协变的。你可以使用:
Map<Integer, Map<String, Integer>> myMap = new HashMap<Integer, Map<String, Integer>>();
^ ^
--------------^------------------- becomes ------^ |
-----------------must remain as type ---------------
在赋值语句的最左边,Map
可以“变成”一个被赋值的 HashMap
,但是同样的规则不适用于出现在泛型参数中的任何类型。
编辑:
正如 @Keppil 所指出的,您可以使用有界通配符语法:
Map<Integer, ? extends Map<String, Integer>> myMap = new HashMap<Integer, HashMap<String, Integer>>();
注意,这种语法不允许向地图中添加条目,但作为一种类型传递给方法时很有用。
一些参考资料:
这是类似的错误
List<Animal> list = new ArrayList<Dog>();
泛型参数类型应该在两端是相同的。没有继承(IS-A)的概念。如果你仍然想使用它,请使用通配符(?)和extend/super关键字,该关键字只能放在等号左侧。
List<Animal> list = new ArrayList<Dog>(); // is not allowed
但是
Animal[] animal = new Dog[10]; //is allowed
animal[0] = new Dog(); // is allowed
如果有人尝试添加扩展Animal类的Cat
对象,它将在后面失败并抛出异常。
animal[1] = new Cat(); //compiles fine but throws java.lang.ArrayStoreException at Runtime.
记住animal[1]
或animal[index]
持有Dog
的引用。因此,Dog
引用变量可以引用Dog
对象而不是Cat
对象。
为了避免这种情况,JSL在范型列表/集合中做出了这样的更改。 这个答案也适用于你的问题(Map
)。
参数化类型应该在两端都是同一类型。
List<Animal> list = new ArrayList<Animal>();
试试这个
Map<Integer, ? extends Map<String, Integer>> myMap = new HashMap<Integer, HashMap<String, Integer>>();
Set<Number> set = new HashSet<Integer>();
不允许这样操作,因为这样会向整数的HashSet中添加一个Double类型的值。
set.add(1.0)
Set<? extends Number> set = new HashSet<Integer>();
该集合不允许添加除null
以外的任何内容。但是您只能从中读取数字。
您可以在此处找到更多信息:http://docs.oracle.com/javase/tutorial/extra/generics/wildcards.html
Map<Integer, Map<String, Integer>> myMap = new HashMap<Integer, Map<String, Integer>>();
myMap.put(1, new HashMap<String, Integer>());
Map<String, Integer>
不同于HashMap<String, Integer>
,这就是问题所在。
实际上,HashMap实现了Map接口,因此左侧应该是? extends Map<String, Integer>
试试这个:
Map<Integer, HashMap<String, Integer>> myMap = new HashMap<Integer, HashMap<String, Integer>>();
Map<Integer, ? extends Map<String, Integer>> myMap = new HashMap<Integer, HashMap<String, Integer>>();
。 - Keppil