Java下限通配符? super T表示实际类型为T或其父类,支持向集合写入T及子类实例,读取时仅返回Object类型,体现PECS原则中“Consumer-Super”设计思想。

Java 下限通配符(? super T)通过指定类型 T 的下界来控制边界,意思是:实际类型必须是 T 或 T 的任意父类(如 Number、Object),不能是 T 的子类。
边界由 super 关键字和具体类型共同定义
语法 ? super T 中的 T 是下界基准,不是上限。编译器据此推断合法的实际类型范围:
-
List<? super Integer>可以引用List<Integer>、List<Number>或List<Object> - 但不能引用
List<Long>或List<String>——它们与Integer无继承关系 - 也不能引用
List<Comparable>(除非Integer显式实现它,且该接口未被擦除为类型边界)
写入操作受边界严格保护
只有 T 类型或其子类的实例才能安全写入,因为所有父类都能接收子类对象:
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- 向
List<? super Integer>中可添加Integer、int(自动装箱)、new AtomicInteger(5)(若它是Integer子类,但注意Integer是 final,实际中子类极少) - 不可添加
Double或String,编译器会报错——它们不满足“是Integer或其子类”这一条件
读取时边界导致类型信息丢失
由于实际类型可能是 Integer、Number 或 Object 中任意一个,编译器无法确定确切返回类型:
立即学习“Java免费学习笔记(深入)”;
- 从
List<? super Integer>调用get(0),返回类型只能是Object - 若需当作
Integer使用,必须显式强转:(Integer) list.get(0),但运行时可能抛ClassCastException - 这种设计不是缺陷,而是边界控制的自然结果:写入安全优先,读取灵活性让位于类型确定性
边界控制服务于 PECS 原则
? super T 的边界逻辑紧扣“Consumer-Super”原则:
- 它专为消费数据(即往集合里塞东西)设计,边界确保“能收得下”
- 常见于工具方法,如
Collections.copy(dest, src)中dest参数声明为List<? super T> - 边界越宽(如用
? super Object),灵活性越高,但实际意义趋近于List<Object>;边界越窄(如? super Integer),写入约束越明确,类型安全性越强

















