首页 > 代码库 > 泛型2
泛型2
万用字符(wildcard)
以动物Animal类为例,怎样才能创建出一种ArrayList<?>里面既可以保存ArrayList<Dog>,又可以保存ArrayList<Cat>?
public void takeAnimals(ArrayList<? extends Animal> animals){ //泛型中extends同时代表继承和实现。
for(Animal a : animals){
a.eat();
}
}
我们可以这样调用该函数:
ArrayList<Cat> cat = new ArrayLIst<Cat>();
cat.add(new Cat());
cat.add(new Cat());
cat.add(new Cat());
takeAnimals(cat);
也可以这样调用:
ArrayList<Dog> dog = new ArrayLIst<Dog>();
dog.add(new Dog());
dog.add(new Dog());
dog.add(new Dog());
takeAnimals(dog);
但是,请记住!在使用ArrayList<? extends Animal>的时候,编译器会阻止任何可能破坏引用参数所指集合的行为:
你能够调用引用参数中的任何对象,但不能加入新元素。
比如:animals.add(new Cat()); 就过不了编译关。
同样的实现,还有另一种写法:
public <T extends Animal> void takeThing(ArrayList<T> list) 和
public void takeThing(ArrayList<? extends Animal> list) 执行是一样一样的。
为什么这里一个用T一个用?
举个例子:
public <T extends Animal> void takeThing(ArrayList<T> one, ArrayList<T> two)
public void takeThing(ArrayList<? extends Animal> one, ArrayList<? extends Animal> two)
如果两个参数都是extends自Animal那么只声明一次会比较有效率。
泛型2