使用泛型和通配符均可以让一个方法所表示的算法逻辑适应多种类型。
Java中具有继承关系的类A、B(A extends B
)它们的集合List<A>
和List<B>
之间是没有继承关系的,
能够使用泛型或通配符来让一个方法支持同时接受List<A>
和List<B>
。java
这里分别定义类Animal、Dog和Cat,很显然,Dog和Cat是Animal的子类。
它们的简单定义以下:算法
abstract class Animal { public abstract boolean afraidOf(Animal other); } class Cat extends Animal { @Override public boolean afraidOf(Animal other) { if (other instanceof Dog) { return true; } return false; } } class Dog extends Animal { @Override public boolean afraidOf(Animal other) { if (other instanceof Cat) { return false; } return true; } }
上面Animal类定义了boolean afraidOf(Animal other)
方法,表示一个动物是否惧怕另外一个动物。ide
能够看到Cat和Dog有着不一样的表现。code
假设有下面需求:
从一个List<Animal>
中找到某个Animal对象惧怕的全部其它动物。
对应有如下的API方法:对象
public List<Animal> findScaredAnimals(List<Animal> animals, Animal who) { //... }
若是这时有List<Dog>
或者List<Cat>
这种,也应该是支持的。
能够经过通配符或者泛型方法实现。继承
使用List<? extends Animal>
这样的形参,就能够接收集合项为Animal子类的任意List。class
public List<Animal> findScaredAnimals(List<? extends Animal> animals, Animal who) { //... }
这时就能够这样调用了:泛型
List<Dog> dogs; .... findScaredAnimals(dogs, animal); ...
其余Animal子类的List都是能够的。List
抛开实际意义,假设须要findScaredAnimals()中,返回值和参数对应的具体Animal子类型是一致的,那么就须要用到泛型了:方法
public <T extends Animal> List<T> findScaredAnimals(List<T> animals, T who) { //... }
能够看到,泛型类型参数T同时约束了多个地方。
泛型参数也能够是多个的,并且之间存在关系。
以上经过一个不太实际的案例说明了使用泛型和通配符来解决List泛型集合之间的“匹配”问题。这也是它们的主要用途之一。
(本文使用Atom编写)