? super T 的核心目的是安全地向集合写入 T 类型或其子类型的对象;因实际类型是 T 或其父类,故仅允许添加 T 及其子类实例(如 Integer),禁止添加父类(如 Number)或无关类型(如 String)。

Java 泛型中使用 ? super T(下限通配符)的核心目的,就是安全地向集合写入 T 类型或其子类型的对象。它不追求“读得方便”,而是确保“写得安全”。
为什么只能写入 T 及其子类?
声明 List super Integer> 时,编译器只知道这个列表的实际元素类型是 Integer 或它的某个父类(比如 Number、Object),但不确定到底是哪一个。所以:
- 往里加
Integer是安全的——因为Integer能赋值给Number,也能赋值给Object; - 往里加
String不合法——String和Integer没有继承关系,无法保证兼容; - 往里加
Number也不允许——因为实际类型可能是Integer,而Number不是Integer的子类,不能无条件放入。
写入操作的正确写法
你只能传入 T 类型或其子类的实例。常见写法包括:
list.add(new Integer(42));-
list.add(100);(自动装箱为Integer) -
list.add((Integer) someObj);(前提是能确保类型安全)
注意:list.add(null) 总是允许的,因为 null 可以赋给任何引用类型。
典型应用场景:消费者方法
下限通配符最常用于“接收数据”的工具方法,例如:
分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。
public static <t> void addAll(List super T> dest, List<t> src) {
for (T item : src) {
dest.add(item); // ✅ 安全:dest 能容纳 T
}
}</t></t>
调用时可以灵活传入不同上界的目标列表:
-
addAll(numbers, integers);(numbers是List) -
addAll(objects, integers);(objects是List)
不能做的事:避免常见误用
以下写法都会编译失败:
-
list.add(new Number());——Number是抽象类,且不是Integer的子类; -
list.add(3.14);——Double不是Integer的子类; -
list.add(new Object());——Object是父类,但不是Integer的子类,不满足“可写入”条件。
关键记住:写入时只认 T 及其子类,不认 T 的父类或无关类型。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










