在 Java 泛型里,“上下界”通常指的是 上界(Upper Bound) 和 下界(Lower Bound),用关键字 extends 和 super 来定义。下面从概念 → 语法 → 使用场景 → 记忆口诀一步步讲清楚。
规定泛型 “只能是某个类或其子类”
<T extends Number>
✅ 表示:
NumberInteger、Double)规定泛型 “只能是某个类或其父类”
<? super Integer>
✅ 表示:
IntegerNumber、Object)| 写法 | 含义 | 用于 |
|---|---|---|
<T extends A> |
T 是 A 或 A 的子类 | 定义泛型类、方法 |
<? extends A> |
未知类型,但一定是 A 或子类 | 生产者(读取) |
<? super A> |
未知类型,但一定是 A 或父类 | 消费者(写入) |
⚠️ 注意:
super 不能用于定义泛型类,只能用于 通配符
// ✅ 可以
class Box<T extends Number> {}
// ❌ 不可以
class Box<T super Integer> {}
List<? extends Number> list = new ArrayList<Integer>();
Number n = list.get(0); // ✅ 安全
// list.add(1); // ❌ 编译错误
为什么不能 add?
编译器只知道“是 Number 的子类”,但不知道 具体是哪个
可能是Integer,也可能是Double,不能乱加
✅ 适合读取数据(生产者)
List<? super Integer> list = new ArrayList<Number>();
list.add(1); // ✅
// Integer i = list.get(0); // ❌
Object o = list.get(0); // ✅ 只能当 Object 用
为什么能 add?
一定是 Integer 或其父类,装 Integer 不会出错
✅ 适合写入数据(消费者)
PECS:Producer Extends, Consumer Super
| 场景 | 用哪个 |
|---|---|
| 只读取(生产数据) | <? extends T> |
| 只写入(消费数据) | <? super T> |
| 又读又写 | 不要用通配符 |
public static <T> void copy(
List<? super T> dest,
List<? extends T> src
) {}
src:生产者(只读)dest:消费者(只写)public <T extends Comparable<T>> T max(T a, T b) {
return a.compareTo(b) > 0 ? a : b;
}
public void addNumbers(List<? super Integer> list) {
list.add(1);
list.add(2);
}
❌ 误区 1:<? extends Object> 很常用
✅ 其实等价于 <?>,没意义
❌ 误区 2:super 能定义泛型类
✅ 不能,只能用于通配符
❌ 误区 3:List<Object> 能接 List<Integer>
✅ 不能,泛型 不协变
上界限制“最高是谁”,下界限制“最低是谁”
读用 extends,写用 super
如果你愿意,我可以帮你:
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。