上界通配符(? extends Type)
在Java中,? extends Type
是一个上界通配符,表示参数化类型的上限是Type
。这意味着容器可以持有Type
类型的任何对象或者Type
的子类型对象。
使用场景
这种类型的通配符常用于泛型方法中,允许方法接受Type
的实例或其子类型的集合。这同样基于PECS原则,即如果你需要一个提供(生产)指定类型元素的集合,使用? extends
。
例子
假设我们有以下类的层次结构:
class Animal {}
class Dog extends Animal {}
class Cat extends Animal {}
现在,我们有一个方法,它的目的是从一个集合里读取Animal
对象:
public void processAnimals(List<? extends Animal> animals) {
for(Animal animal : animals) {
// 这里可以安全地调用Animal类的方法
}
}
这个方法接受的参数是一个列表,这个列表的类型是Animal
或Animal
的任何子类型。因此,以下的调用是有效的:
List<Animal> animalList = new ArrayList<>();
List<Dog> dogList = new ArrayList<>();
List<Cat> catList = new ArrayList<>();
processAnimals(animalList); // 正确:列表的类型正好是Animal
processAnimals(dogList); // 正确:Dog是Animal的子类型
processAnimals(catList); // 正确:Cat是Animal的子类型
在这个例子中,无论是Animal
列表、Dog
列表还是Cat
列表,都可以传递给processAnimals
方法,因为它们都满足? extends Animal
的条件。这样做的好处是你可以将方法的使用范围扩展到更多的子类型,同时能够在提取元素时保持类型安全。
遍历
使用? extends Type
时,遍历集合是安全的,因为你确切知道集合中的每个元素至少是Type
类型。因此,你可以调用Type
中定义的方法,而不需要进行任何类型转换。
例如
public void processAnimals(List<? extends Animal> animals) {
for(Animal animal : animals) {
// 可以直接调用Animal类的方法,无需类型转换
}
}
总结
? extends Type
通配符的使用提高了代码的灵活性,它允许你编写能够接受更多子类型集合的泛型方法,同时保证了从这些集合中提取元素的类型安全。这是PECS原则中的“Producer Extends”部分,适用于你的集合是提供或生产元素的情况。在遍历这样的集合时,可以直接处理Type
类型的元素,无需担心类型转换的问题。