Collection.add和Collection.addAll

时间:2017-08-09 11:54:53

标签: java generics

boolean addAll(Collection<? extends E> c);
boolean add(E e);

Collection.addAll中的参数是Collection<? extends E>,我认为这意味着E的所有子类都可以使用,但Collection.add中的参数是E.我认为这意味着只能使用E类。 / p>

那么为什么E的子类不能成为这种方法的参数呢?例如<T extends E> boolean add(T t);

1 个答案:

答案 0 :(得分:1)

对于类型为T的Collection,上限通配符是必需的。让我们采用以下结构

class Animals{}
class Dog extends Animals{}
class Cat extends Animals{}

class Container<T>{
    void add(T t){};
    void addAll(Collection<T> t){};
}

我们实例化它并像这样使用它

ArrayList<Dog> dogs = new ArrayList<>();
dogs.add(new Dog());

ArrayList<Cat> cats = new ArrayList<>();
cats.add(new Cat());

Container<Animals> animalContainer = new Container<>();
animalContainer.add(dogs.get(0)); // will work since add(T t)
animalContainer.addAll(cats); // will not work since addAll(Collection<T> t)

它不能与addAll(Collection<T> t)一起使用的原因是容器只接受T类型Animal,但由于cat列表的类型为Cat它违反了约束条件。

由于Animal可以是DogCatAnyOtherConcreteAnimal。通过将其更改为上限通配符

void addAll(Collection<? extends T> t){};

你说你希望一个具有Animals具体类型而不是 T的集合Container<Animals>。现在这将再次起作用

 animalContainer.addAll(cats); // will work since addAll(Collection<? extends T> t)