?表示未知但确定的类型,用于变量/参数/返回值中,能读(元素视为Object)不能写(仅null),适用于只消费不写入的场景;需双向操作时应选用? extends T、? super T或具体泛型。

Java 泛型通配符 ? 本身不表示具体类型,而是代表“某个未知但确定的类型”。它不能直接用于声明泛型类或创建实例,主要用在变量、参数和返回值中,配合读写规则保障类型安全。关键在于:**能读不能写(除 null 外)**。
无界通配符 > 的读取方式
使用 List> 类型的集合时,编译器允许你读取元素,但所有元素都被视为 Object 类型:
- 可以安全遍历并赋值给
Object变量,例如:Object obj = list.get(0); - 不能直接强转为具体类型,如
String s = (String) list.get(0);虽然语法通过,但失去泛型保护,运行时可能出错 - 推荐做法是先用
instanceof判断再转型,或改用带边界的通配符(如? extends String)提升安全性
无界通配符 > 的写入限制
向 List> 中添加数据几乎被完全禁止:
- 只允许写入
null,因为null是所有引用类型的合法值 -
list.add("hello");或list.add(123);均编译失败 —— 编译器无法确认目标集合实际接受什么类型 - 这种限制不是设计缺陷,而是防止破坏类型一致性,比如往
List<integer></integer>引用的List>中误加字符串
什么时候该用 >?
适合只做“消费”动作、不关心内部类型、也不需要写入的场景:
立即学习“Java免费学习笔记(深入)”;
- 打印日志:
public static void logSize(List> list) { System.out.println("size: " + list.size()); } - 判空或校验结构:
if (list != null && !list.isEmpty()) { ... } - 作为方法参数接收任意泛型列表,仅调用
size()、isEmpty()、contains()等不依赖元素类型的通用方法
如果既要读又要写,怎么办?
? 本身不适合双向操作。应按需求切换通配符类型:
- 侧重读取(如统计、过滤)→ 用
? extends T,可安全读为T,但不可写 - 侧重写入(如收集、归并)→ 用
? super T,可安全写入T及其子类,但读出只能是Object - 明确知道类型 → 直接用具体泛型,如
List<string></string>,读写都自由


















