? super t 表示泛型类型为 t 或其任意父类,用于安全写入 t 类型对象;可向 list

Java 中的下限通配符 ? super T 并不是“限制父类类型”,而是**允许泛型参数取 T 或其任意父类(包括 T 本身)**。它的作用是放宽类型约束,让方法能接受更宽泛的集合类型,但前提是保证写入安全。
它怎么定义下界:语法与含义
? super Integer 表示“某个未知类型,但它至少是 Integer 或它的父类”。也就是说,这个通配符匹配:
-
List<integer></integer>(T 本身) -
List<number></number>(Integer 的直接父类) -
List<object></object>(Number 的父类,也是 Integer 的祖先) -
List<serializable></serializable>、List<comparable>></comparable>等所有 Integer 实现的接口类型(只要它们是 Integer 的父类型)
它为什么只允许写入 T,不能安全读取?
因为编译器只知道“元素类型 ≥ T”,但不确定具体是哪一个父类。例如:
- 你传入
List<number></number>,get(0)返回Number - 你传入
List<object></object>,get(0)返回Object - 编译器无法统一返回类型,所以统一按最顶层的公共父类
Object处理
所以:list.add(new Integer(42)) 总是合法;但 Integer i = list.get(0) 编译失败,必须写成 Object o = list.get(0)。
它在方法设计中怎么体现“限制父类”?
这种“限制”其实是对**实参类型范围的声明**,不是运行时检查。比如:
public static <t> void copyTo(List super T> dest, List<t> src) {
for (T item : src) {
dest.add(item); // ✅ 安全:dest 肯定能装下 T
}
}</t></t>
调用时:
-
copyTo(new ArrayList<number>(), intList)</number>→ 合法 -
copyTo(new ArrayList<object>(), intList)</object>→ 合法 -
copyTo(new ArrayList<string>(), intList)</string>→ 编译报错(String 不是 Integer 的父类)
这里 ? super Integer 就是在告诉编译器:“只接受 Integer 及其父类的集合”,这就是它对父类类型的“限制”逻辑。
常见误区:super 关键字 ≠ ? super T
super 是子类中调用父类构造器或方法的关键字,和泛型通配符无关。你不能写 List<super integer></super>,那是语法错误。真正起作用的是 ? super Integer 这个整体符号,其中 super 只是关键字标记,表示“下界”,不参与继承调用。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











