author
type
status
date
slug
summary
tags
category
icon
password
在Java泛型中,上下界限定符(
<? extends T> 和 <? super T>)用于约束泛型类型的范围,增强类型安全性,同时解决泛型类型的灵活性问题。以下通过具体场景和示例解释它们的核心区别和应用。1. 上界限定符 <? extends T>(生产者模式)
含义:
表示泛型类型必须是
T 或其子类,即“上限是T”。用途:
• 只读场景:从泛型对象中安全读取数据。
• 不能写入:因为无法确定具体子类型(可能破坏类型安全)。
示例1:读取数据
关键点:
•
sum 方法可以接受 List<Integer> 或 List<Double>,因为它们的元素都是 Number 的子类。
• 不能添加元素:list.add(100) 会编译错误,因为实际类型可能是 Double,而 100 是 Integer。2. 下界限定符 <? super T>(消费者模式)
含义:
表示泛型类型必须是
T 或其父类,即“下限是T”。用途:
• 只写场景:向泛型对象安全写入数据。
• 可以读取:但读取时类型会被视为
Object(需强制转换)。示例2:写入数据
关键点:
•
addIntegers 可以向 List<Number> 或 List<Object> 添加 Integer,因为 Integer 是它们的子类。
• 可以读取为Object:Object obj = list.get(0) 是允许的,但可能需要强制转换。3. PECS原则(Producer-Extends, Consumer-Super)
这是使用上下界限定符的核心原则:
• Producer(生产者):产生数据的对象(如从集合读取数据),使用
<? extends T>。• Consumer(消费者):消费数据的对象(如向集合写入数据),使用
<? super T>。示例3:结合PECS的通用方法
说明:
•
src 使用 extends 保证读取安全,dest 使用 super 保证写入安全。4. 常见误区与解答
误区1:List<? extends Number> 和 List<Number> 的区别
List<? extends Number>是“某种Number子类的List”,而List<Number>是“明确为Number的List”。
误区2:<? super T> 不支持读取
总结
限定符 | 应用场景 | 读写规则 |
<? extends T> | 生产者(读取数据) | 只读,不能写入(除 null) |
<? super T> | 消费者(写入数据) | 可写入,读取为 Object |
核心思想:
•
extends 放宽读取限制,确保读取的数据类型统一。•
super 放宽写入限制,确保写入的数据类型符合要求。- 作者:Sean Liu
- 链接:https://blog.liusx.dev//article/1d1749a0-584b-8097-b2f8-dcb1a564fa14
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。









