我是仿制药的新手,所以不确定我哪里出错......
我有一个名为Cat,Dog和Rabbit的类,它们实现了Animal的接口。
以下代码将编译
Set<? extends Animal> animalSet;
Set<Dog> dogSet = new HashSet<Dog>();
animalSet = dogSet;
但以下代码不会
Map<String, Set<? extends Animal>> animalMap;
Map<String, Set<Dog>> dogMap = new HashMap<String, Set<Dog>>();
animalMap = dogMap; // this line will not compile
编译器说类型不兼容。我哪里错了?
更新
感谢大家的帮助
我通过添加另一个通配符更改了第一行代码 以下代码将编译
Map<String, ? extends Set<? extends Animal>> animalMap;
Map<String, Set<Dog>> dogMap = new HashMap<String, Set<Dog>>();
animalMap = dogMap;
另请参阅下面Cyrille Ka给出的解决方案 - 使用putAll()将值从dogMap传输到animalMap,而不是将dogMap分配给animalMap。
答案 0 :(得分:7)
基本上,当你写:
Map<String, Set<? extends Animal>> animalMap;
您声明地图的任何值都是一个可以包含任何类型为Animal子类的对象的集合。那么客户端代码编写是完全合理的:
animalMap.put("miaow", aCatSet);
其中acatSet
是Set<Cat>
。
但dogMap
无法接受Set<Cat>
作为值,它只能接受Set<Dog>
。因此,存在类型不兼容的可能性,这就是禁止这种结构的原因。
编辑:至于如何解决这个问题,取决于您想要做什么。如果您在某个地方有dogMap
并希望将其内容放入animalMap
,那么您只需复制以下内容:
Map<String, Set<? extends Animal>> animalMap = new HashMap<String, Set<? extends Animal>>();
Map<String, Set<Dog>> dogMap = new HashMap<String, Set<Dog>>();
/// fill dogMap
animalMap.putAll(dogMap);
答案 1 :(得分:3)
因为Java是强类型的:? extends Animal
不是Dog
,它可能是Cat
或其他子类。
例如,在这种情况下,如果您定义Set<? extends Animal> animalSet
,我可以合法地执行animalSet.add(new Cat())
,对吧?但是您希望使用animalSet
初始化此Set<Dog>
,这将不再允许animalSet.add(new Cat())
。这是不一致的,这就是不允许的原因。
答案 2 :(得分:2)
问题的解决方案是:
Map<String, ? extends Set<? extends Animal>> animalMap;
Map<String, Set<Dog>> dogMap = new HashMap<String, Set<Dog>>();
animalMap = dogMap;
因为Set<Dog>
不是Set<? extends Animal>
,而是扩展它。
答案 3 :(得分:1)
至于为什么 - 让我稍后再说。 现在请注意,这会编译:
Map<String, Set<? extends Animal>> animalMap;
Map<String, Set<? extends Animal>> dogMap
= new HashMap<String, Set<? extends Animal>>();
Set<Dog> dogMapVal = new HashSet<Dog>();
dogMap.put("fido", dogMapVal);
animalMap = dogMap;
答案 4 :(得分:1)
将以下逻辑(基于this answer)应用于您的问题:
Dog
IS Animal
Set<Dog>
IS Set<? extends Animal>
Map<String, Dog>
不 Map<String, Animal>
因此:
Map<String, Set<Dog>>
不 Map<String, Set<? extends Animal>>
这就是编译器在你上一次任务中抱怨的内容。
答案 5 :(得分:0)
此处父子关系不起作用,如父p = child。 oracle docs
答案 6 :(得分:0)
因为狗不等于动物,只能扩展它。
图片,如果有代码,你在这个代码的某处使用,你把狗放在里面。之后,你又想再次使用它,你认为你把狗放在这里,所以你回来了。但是,如果有人,将猫或兔子放入其中?
所以这就是原因。