Java 列表泛型具有多个边界

标签 java list generics collections bounds

我很难理解为什么以下代码不起作用:

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>意思是“作为 AnimalIQuadruped 的子类型的特定类型”,而不是“作为 AnimalIQuadruped 的子类型的任何类型”

之所以很难理解这种差异,是因为在日常思维中我们并没有明确地表达这种区别。例如,如果您同意与某人一起去餐馆吃午餐,而他们说“下周的任何一天都适合我”,您自然而然地知道这意味着您需要在同一天出现。并不是说你可以随时去,他们就会在那里。

在这种情况下,不能保证E来电者选择的肯定是Dog ,所以你的代码将无法工作。

明显错误的解决方案是指定 <E extends Dog> ,因为它可以保证EDog 的子类型。然而,由于完全相同的原因,这是错误的,E可以是 Dog 的任何子类型,比方说EPoodle ,所以当您创建 List<Poodle> 时,您将无法将 new Dog()在那里,因为它不是 Poodle .

正确的界限是<E super Dog> ,因为这意味着 E绝对是您可以转换 Dog 的类型实例到.可能是Dog本身,它可能是 AnimalIQuadruped甚至 Object 。但它保证你可以输入 Dog在列表中。

这个原则的名字是PECS:生产者扩展,消费者 super ,你可以阅读它 here .

关于Java 列表泛型具有多个边界,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31343650/

相关文章:

java - 用于单元测试的 Mock dao

java - 使用元数据在 mysql 中插入查询

java - 好的做法?虚拟对象

java - 用jsp显示图像

c# - C# List<T> 的线程安全给读者

java - HashMap 和列表

c# - 转换为 Tuple<object,object>

java - 从 postgresql 存储过程返回带有列名的结果集

list - 拆分列表并在序言中迭代

java - 泛型方法 Java