list

因为 List super Integer> 表示“某个未知类型,但它至少是 Integer 的父类(比如 Number 或 Object)”,编译器只知道下界,不知道上界——写入时靠下界保障安全,读取时因上界不确定,只能退到最宽泛的 Object。
写入为什么只允许 Integer 及其子类
编译器在类型检查阶段确认:只要往集合里加的是 Integer 或它的子类(比如自定义的 MyInt extends Integer),就一定能被所有可能的实际类型容纳:
-
List<integer></integer>当然能存Integer -
List<number></number>能存Integer(因为Integer是Number子类) -
List<object></object>更能存Integer(一切对象都是Object)
但加 Double 就不行——如果实际引用的是 List<integer></integer>,那就会破坏类型约束;编译器禁止这种风险操作。
读取为什么只能是 Object
你无法预知这个通配符实际指向哪个具体类型:
- 它可能是
List<integer></integer>→get(0)返回Integer - 也可能是
List<number></number>→get(0)返回Double或Integer - 还可能是
List<object></object>→get(0)返回String、Thread等任意对象
唯一所有情况都成立的公共类型只有 Object。编译器不猜、不假设,直接限定返回类型为 Object,避免强制转型时的 ClassCastException。
这不是缺陷,而是类型安全的设计取舍
? super T 的定位就是“消费者”——专为写入服务。它用牺牲读取的精确性,换来了写入的灵活性和安全性:
- 你可以把一个方法设计成接收
List super Integer>,让它既能处理ArrayList<integer></integer>,也能处理LinkedList<number></number>,甚至CopyOnWriteArrayList<object></object> - 但一旦需要读取并按具体类型使用元素,就该换用
? extends T或明确的具体泛型类型
泛型擦除后运行时确实只剩原始类型,但这一切的安全边界,全由编译期的这套推理机制守住。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











