super是子类调用父类成员的关键字,而? super t是泛型下界通配符,用于限定类型为t或其父类,支持向集合写入t类型元素,但读取时仅能赋给object。

super 关键字本身不能直接实现“下界通配符”或“向父类集合注入子类对象”的功能。这是对 Java 泛型、通配符和继承机制的常见误解。下面直接讲清楚关键点和正确做法:
super 和下界通配符(? super T)是两回事
super 是用于在子类中调用父类构造器或方法的关键字,比如 super() 或 super.method()。它不参与泛型类型约束。
而 ? super T 是泛型中的**下界通配符**,用于放宽写入限制,常见于 Collection super T> 这类声明中——它表示“能接受 T 类型或其任意父类的集合”,核心用途是:安全地往集合里 add(T)。
历史兼容的父类集合中注入子类对象?看场景
假设你有旧代码:List,现在想往里面加 String、Integer 等子类实例——这完全合法,因为 String 是 Object 的子类,无需泛型通配符或 super。
但如果用泛型增强安全性,正确方式是:
- 想**读取**时保证类型安全 → 用上界:List extends Number>(只能 get,返回 Number)
- 想**写入**子类实例 → 用下界:List super Integer>(可以 add(Integer),但 get() 只能当 Object)
实战示例:用 ? super 实现“兼容旧集合”的安全写入
比如有个工具方法,需把一批 BigDecimal 写入一个可能为 List
public static void addNumbers(List super BigDecimal> target, BigDecimal... nums) {
for (BigDecimal n : nums) {
target.add(n); // ✅ 安全:BigDecimal 是 Number 和 Object 的子类
}
}
调用时:
-
addNumbers(new ArrayList
(), bd1, bd2); → 合法 - addNumbers(new ArrayList → 合法
-
addNumbers(new ArrayList
(), bd1, bd2); → 合法(BigDecimal 是自身的父类)
这里没用到 super 关键字,只用了 ? super BigDecimal ——这才是实现“向更宽泛父类集合写入子类对象”的正解。
为什么不用 super 关键字?
super 不作用于类型参数。你不能写 List











