我很难理解为什么以下代码不起作用:
public <E extends Animal & IQuadruped> void testFunction()
{
List<E> list = new ArrayList<E>();
Dog var = new Dog();
list.add(var);
}
狗如下:
public class Dog extends Animal implements IQuadruped
{
}
我在添加时遇到编译错误:
The method add(E) in the type List<E> is not applicable for the arguments (Dog)
我只是想确保我的列表元素扩展/实现这两个类,并且 Dog 满足这些条件,为什么它不起作用?
谢谢
最佳答案
什么<E extends Animal & IQuadruped>
意思是“作为 Animal
和 IQuadruped
的子类型的特定类型”,而不是“作为 Animal
和 IQuadruped
的子类型的任何类型”
之所以很难理解这种差异,是因为在日常思维中我们并没有明确地表达这种区别。例如,如果您同意与某人一起去餐馆吃午餐,而他们说“下周的任何一天都适合我”,您自然而然地知道这意味着您需要在同一天出现。并不是说你可以随时去,他们就会在那里。
在这种情况下,不能保证E
来电者选择的肯定是Dog
,所以你的代码将无法工作。
明显错误的解决方案是指定 <E extends Dog>
,因为它可以保证E
是 Dog
的子类型。然而,由于完全相同的原因,这是错误的,E
可以是 Dog
的任何子类型,比方说E
是 Poodle
,所以当您创建 List<Poodle>
时,您将无法将 new Dog()
在那里,因为它不是 Poodle
.
正确的界限是<E super Dog>
,因为这意味着 E
绝对是您可以转换 Dog
的类型实例到.可能是Dog
本身,它可能是 Animal
或IQuadruped
甚至 Object
。但它保证你可以输入 Dog
在列表中。
这个原则的名字是PECS:生产者扩展,消费者 super ,你可以阅读它 here .
关于Java 列表泛型具有多个边界,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31343650/