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);
答案 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
可以是Dog
,Cat
,AnyOtherConcreteAnimal
。通过将其更改为上限通配符
void addAll(Collection<? extends T> t){};
你说你希望一个具有Animals
具体类型而不是 T
的集合Container<Animals>
。现在这将再次起作用
animalContainer.addAll(cats); // will work since addAll(Collection<? extends T> t)