java泛型通配符用? extends t(上界,只读)和? super t(下界,可写)限定类型范围,分别适用于读取父类共用数据和写入子类对象;?无界仅支持容器级操作;二者不可混用,且不能用于类声明。

Java 中通过泛型通配符限定参数类型范围,主要靠 ? extends T(上界)和 ? super T(下界)两种形式,配合方法参数、集合变量或返回值使用,实现安全的类型约束与多态兼容。
用 ? extends 限定上界:只能读,不能写
当需要接收“某个类型及其子类”的实例,且只从中读取数据时,用 ? extends T。它表示通配符代表的类型是 T 或 T 的任意子类。
-
适用场景:遍历、获取元素、调用父类共有的方法(如
doubleValue()、toString()) -
典型例子:
List extends Number>可以接收List<integer></integer>、List<double></double>,但不能往里 add 任何具体对象(除了null),因为编译器无法确定实际类型 -
安全操作:
Number n = list.get(0); // ✅ 编译通过,返回值可安全转为 Number String s = list.get(0).toString(); // ✅
用 ? super 限定下界:可以写,读出类型变宽
当需要向集合中写入某类型或其子类的对象,并接受“该类型或其任意父类”的容器时,用 ? super T。它表示通配符代表的类型是 T 或 T 的任意父类。
- 适用场景:向集合添加元素(比如归并、填充)、消费型操作(Consumer)
-
典型例子:
List super Integer>可以接收List<integer></integer>、List<number></number>、List<object></object> -
安全操作:
list.add(123); // ✅ 可以 add Integer 及其子类(如 AtomicInteger) list.add(new Integer(456)); // ✅ Object o = list.get(0); // ⚠️ 只能赋给 Object 或其父类,类型信息变窄
不带限定的 ?:仅用于类型无关的操作
? 表示未知具体类型,适用于不需要知道内部类型、只做容器级操作的场合。
-
能做的:获取长度、清空、判空、获取元素(返回
Object)、赋值给其他?类型引用 -
不能做的:add 任意非 null 元素(编译报错)、调用泛型元素特有方法(如
compareTo()) -
例子:
void printSize(List> list) { System.out.println("size: " + list.size()); // ✅ // list.add("x"); // ❌ 编译错误 }
注意边界规则与常见误区
通配符限定不是万能的,需注意以下关键点:
-
extends 和 super 不能同时出现:Java 不支持
? extends A & super B这类混合写法 -
泛型方法中优先用类型参数,而非通配符:例如
<t extends comparable>> void sort(List<t> list)</t></t>比void sort(List extends Comparable> list)更灵活,支持返回T类型结果 -
通配符不能用于泛型类/接口声明:不能写
class Box extends Number>,只能用于变量、参数、返回值等使用位置 -
多重上界只适用于类型参数(T),不适用于通配符:即
<t extends a b></t>合法,但List extends A & B>是语法错误
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











