我正试图将子类对象放入列表中,但由于作为注释提到的编译器错误,我无法这样做。有人能指出用Java做这件事的正确方法吗?
public class Animal { }
class Util {
private Map<Class<? extends Animal>, List<? extends Animal>> animalListMap;
public void registerAnimal(Class<? extends Animal> animalClass, Animal animalObject) {
if (animalListMap.containsKey(animalClass)) {
//Append to the existing List
List<? extends Animal> animalList = animalListMap.get(animalObject);
animalList.add(animalObject); //COMPILE ERROR- The method add(capture#3-of ? extends Animal) in the type List<capture#3-of ? extends Animal> is not applicable for the arguments (Animal)
} else {
// and the new entry
List<Animal> vos = new ArrayList<Animal>();
vos.add(animalObject);
animalListMap.put(animalClass, vos);
}
}
}发布于 2013-12-05 04:21:17
你宣布
List<? extends Animal> animalList = animalListMap.get(animalObject);? extends Animal是一个以Animal类为界的通配符。因此animalListMap.get(animalObject);可以返回一个List<Donkey>、List<Mouse>、List<Pikachu>,假设Donkey、Mouse和Pikachu都是Animal的子类。但是,通过通配符,您可以告诉编译器,只要它是Animal的子类型,就不关心实际类型是什么。
因为您不知道它是什么,所以实际上不能向它添加任何东西(除了null)。如果您得到的是一个List<Pikachu>,但是animalObject实际上是引用一个Donkey对象,那么您就会遇到问题。这就是为什么编译器不让这段代码编译。
如果您有一个List<Animal>,那么您可以添加任何具有Animal类型或父类型的对象。
发布于 2013-12-05 04:23:51
因为animalList是一个扩展动物的列表,但可能不是具体的动物。换句话说,它可能只限于某一种动物,例如,你可以有一张狮子、老虎或熊的名单(哦,天啊!)
同样,您的代码也容易出现异常,请考虑下面的调用代码示例:
myUtil.registerAnimal(Zebra.class, new Tiger());发布于 2013-12-05 04:26:26
你必须改变这个声明
private Map<Class<? extends Animal>, List<? extends Animal>> animalListMap;如果你想在名单上添加动物。
List<? extends Animal>>指示编译器不允许向该列表添加除null以外的任何内容。
https://stackoverflow.com/questions/20391297
复制相似问题