? super T表示“某个类型,必须是T或T的父类”,用于安全添加元素,如List<? super Integer>可接收Integer,但取出元素只能视为Object;典型场景是通用收集器和JDK的Collections.addAll。

什么是 ? super T
它表示“某个类型,必须是 T 或 T 的父类”。比如 List<? super Integer> 可以指向 ArrayList<Integer>、ArrayList<Number>,甚至 ArrayList<Object>。关键不是“它是什么类型”,而是“它能接收什么”——只要能装下 Integer,就合法。
典型使用场景:往集合里安全添加元素
当你写一个工具方法,目标是把一批 Integer 塞进某个集合,但不关心这个集合具体声明成什么类型(只要能存得下整数),就该用 ? super Integer。
- ✅ 允许调用
add(Integer)、addAll(Collection<Integer>) - ❌ 不能把
get(0)直接当Integer用,只能赋给Object - 常见于 JDK 工具方法,比如
Collections.<T>addAll(collection, elements...)内部就是用? super T实现的
一个实用例子:通用收集器
下面这个方法能把任意 Integer 列表的内容,追加到一个更宽泛的目标容器中:
public static void collectIntegers(List<? super Integer> target, List<Integer> source) {
target.addAll(source); // ✅ 安全:target 肯定能容纳 Integer
}
调用时可以这样传参:
立即学习“Java免费学习笔记(深入)”;
collectIntegers(new ArrayList<Number>(), List.of(1, 2, 3))collectIntegers(new ArrayList<Object>(), List.of(4, 5))collectIntegers(new ArrayList<Integer>(), List.of(6))
但如果传 new ArrayList<String>() 就会编译失败——String 不是 Integer 的父类,不满足 ? super Integer 约束。
和 extends T 的关键区别
别只记“上界/下界”,要盯住行为:
-
? extends Number→ 你能从里面取Number,但不能往里塞任何东西(除了null) -
? super Integer→ 你能往里面塞Integer(或它的子类,如int自动装箱),但取出来只能当Object用
一句话记住:需要“塞数据”,选 super;需要“拿数据”,选 extends。


















