java泛型边界限定是理解并正确使用extends和super约束类型参数,而非计算;它限制的是类型关系:? extends t表示某未知类型是t或其子类。

一、边界到底在“限”什么?
边界限定的不是数值,而是**类型关系**:
-
`? extends T`:表示“某个未知类型,但它是 T 或 T 的子类”。比如 `List extends Number>` 可以是 `ArrayList
`、`LinkedList `,但不能是 `ArrayList `。 -
`? super T`:表示“某个未知类型,但它是 T 或 T 的父类”。比如 `List super Integer>` 可以是 `ArrayList
`、`ArrayList - 注意:泛型类型变量本身(如 `
>`)的边界,擦除后会变成上界(如 `Comparable`),不是 Object 。
二、读写操作怎么选边界?
这是面试高频考点,核心是 PECS 原则(Producer Extends, Consumer Super):
- 如果集合主要用于往外取数据(读),用 `? extends T`——因为所有元素都能安全转成 T 或其父类(如 `Number n = list.get(0)`)。
- 如果集合主要用于往里塞数据(写),用 `? super T`——因为 T 及其子类一定能放进它的父类型容器里(如 `list.add(new Integer(42))`)。
- 既读又写?那就别用通配符,直接用具体泛型类型,比如 `List
`。
三、为什么不能混着来?
编译器会根据边界严格限制操作,这是类型安全的保障:
- `List extends Number>` 允许读出 `Number`,但禁止 `add(...)`——因为你不知道容器实际是 `Integer` 还是 `Double`,加错类型会破坏一致性。
- `List super Integer>` 允许 `add(new Integer(1))` 或 `add(new Long(2))`(Long 是 Integer 的兄弟,不行!注意:只能 add Integer 及其子类,如 `new AtomicInteger()`;但 `Long` 不行,它不是 Integer 子类),但读出来的只能是 `Object`——因为编译器只知道它至少能装下 Integer,但不确定具体是什么类型。
- 错误示例:`List super Integer> list = new ArrayList
();` 直接编译失败,因为 String 不是 Integer 的父类。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











