?表示未知具体类型,是编译器放宽泛型约束的占位符,用于解决泛型不变性问题;适用于只读、不写入、不关心具体类型的场景,如遍历打印(元素统一为Object)、调用size()等非泛型方法,但禁止add/set(除null外)。

泛型通配符 ? 表示“未知的具体类型”,它不是真实类型,而是编译器用来放宽泛型约束的占位符。它的核心作用是解决 Java 泛型的不变性问题——比如 List 和 List 是两个完全独立的类型,不能直接赋值或传参,而用 List> 就能同时接收两者。
什么时候该用 ?(无界通配符)
适合只读、不写入、不关心具体类型的操作场景:
- 遍历并打印元素(统一按
Object处理) - 判断是否为空、获取长度、清空集合等非泛型方法调用
- 作为工具方法参数,避免为每种类型重复写重载(如日志记录、序列化入口)
能做什么?不能做什么?
声明为 List> 后,编译器只允许安全操作:
- ✅ 可以读取元素,但只能接收为
Object类型(例如for (Object o : list)) - ❌ 不能调用
add()、set()等写入方法(除null外),否则编译失败 - ✅ 可以调用
size()、isEmpty()、clear()等非泛型方法
? 和 的区别别搞混
二者定位不同,不能互相替代:
-
void print(List> list):方法不依赖具体类型,一次适配所有List子类,简洁通用 -
:方法内部可能要用到void print(List list) T(比如返回T、做类型判断、或传给其他泛型方法),需要类型一致性 - 如果方法要往集合里加元素,必须用
,不能用?——因为编译器无法验证你加的值是否匹配那个“未知类型”
一个实用例子:安全又通用的打印方法
下面这个方法能接收 List、List、List 任意一种,且不会引发类型错误:
public static void printAll(List> list) {<br> for (Object item : list) {<br> System.out.println(item);<br> }<br>}
注意:循环里用的是 Object item,不是 String item 或 Integer item——这正是 ? 的安全边界体现。











