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
- 链接:http://liusx.top/article/1d1749a0-584b-8097-b2f8-dcb1a564fa14
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。