一、泛型通配符与PECS原则
Java泛型引入通配符?解决类型未知问题。<? extends T>(上界通配符)用于安全读取(Producer),而<? super T>(下界通配符)则专为安全写入(Consumer)设计,对应PECS原则(Producer-Extends, Consumer-Super)。
二、super通配符深度解析
- 定义:
<? super T>表示未知类型,但必须是T或其父类(含Object)。 - 核心能力:允许安全写入
T及其子类对象到集合。 - 代价:读取元素时,类型信息丢失,只能视为
Object。 - 类型安全:编译器确保写入操作符合
T类型约束,避免运行时错误。
三、super通配符实战示例
java
// 示例1:安全写入任意Number子类
class DataSink {
// 可安全接收Number及其子类 (Integer, Double...)
static void addNumbers(List<? super Number> list) {
list.add(10); // Integer
list.add(3.14); // Double
// list.add("Hello"); // 编译错误! String不是Number子类
// 读取受限:只能作为Object处理
Object obj = list.get(0);
}
}
public static void main(String[] args) {
List<Object> objectList = new ArrayList<>();
List<Number> numberList = new ArrayList<>();
DataSink.addNumbers(objectList); // 合法:Object是Number父类
DataSink.addNumbers(numberList); // 合法:Number本身
}
java
// 示例2:PECS原则经典应用 - Collections.sort()
class Animal {}
class Dog extends Animal {}
// 能比较Animal及其子类(如Dog)的Comparator
void sortDogs(List<Dog> dogs, Comparator<? super Dog> comp) {
Collections.sort(dogs, comp); // 安全使用Comparator<Animal>
}
Comparator<Animal> animalComparator = (a1, a2) -> {...};
List<Dog> kennels = new ArrayList<>();
sortDogs(kennels, animalComparator); // 复用父类比较器!
四、关键理解与使用场景
- 写入优先:当API需要写入泛型集合时,优先使用
<? super T>。 - 提升灵活性:允许方法接收更宽泛的容器类型(如
List<Object>接收List<? super Number>)。 - 典型场景:
-
- 集合复制 (
Collections.copy(List<? super T> dest, List<? extends T> src)) - 带比较器的排序方法
- 回调接口中消费泛型对象
- 集合复制 (
结论:super通配符是Java泛型实现安全写入和API灵活性的关键武器。深刻理解其"下界"特性及PECS原则,能显著提升泛型代码的健壮性与复用性,尤其在设计通用库和操作集合时威力尽显。
640

被折叠的 条评论
为什么被折叠?



