Java通配符仅用于变量声明等使用位置,不可定义泛型类或方法;? extends T支持读取(上界)、? super T支持写入(下界)、?表示未知类型仅支持Object操作。

Java 中通配符不能用于定义泛型类或泛型方法的类型参数,只能用在变量声明、方法参数、返回值或字段类型中,用来放宽类型兼容性限制。核心是通过 ? extends T 或 ? super T 表达“未知但受约束”的类型。
使用 ? extends T 限定上界(读取友好)
表示该位置接受 T 类型或其任意子类型,适用于只读场景——你可以安全地从中取出 T 类型的对象,但不能写入(除了 null)。
- 语法:
Collection<? extends Number>可接收List<Integer>、Set<Double>等 - 能调用的方法仅限于
Number及其父类定义的(如doubleValue()、toString()) -
list.add(new Integer(5))编译失败:编译器无法确认具体子类型,禁止写入 - 常见用途:工具方法如
public static double sum(Collection<? extends Number> nums)
使用 ? super T 限定下界(写入友好)
表示该位置接受 T 类型或其任意父类型,适用于只写或消费场景——你可以安全地向其中添加 T 类型实例,但读出时只能当作 Object。
- 语法:
List<? super Integer>可接收List<Number>、List<Object>,但不能接收List<Long> - 可以执行
list.add(10)或list.add(new Integer(42)),因为 Integer 是所有允许类型的子类 - 读取时只能写成
Object obj = list.get(0);无法直接转为 Integer 或 Number(类型不安全) - 典型应用:
Collections.<Integer>addAll(List<? super Integer>, Integer...)
注意通配符不能出现在泛型定义处
下面这些写法是非法的:
立即学习“Java免费学习笔记(深入)”;
-
class Box<? extends CharSequence> { ... }❌(通配符不能作类型参数) -
public <? super String> void method() { ... }❌ -
interface List<?> extends Collection<?>❌
正确做法是把通配符留在使用侧,例如:Box<String> 类本身保持不变,而方法参数声明为 Box<? extends CharSequence>。
无限定通配符 ? 的作用
List<?> 表示“某种未知类型”,仅可用于不依赖具体类型的操作,比如判空、获取大小、遍历(元素视为 Object)。
- 可赋值:
List<String> strs = new ArrayList<>(); List<?> wild = strs; - 不能添加任何非 null 元素:
wild.add("x")编译失败(连 String 都不被允许) - 适合编写通用工具方法,如
public static int size(List<?> list)


















