List<?>是只读友好容器:可遍历、获取大小、判空、清空,元素只能作Object处理;仅允许add(null),禁止添加其他值;适用于不依赖具体类型的通用工具方法。

只读操作:用 ? 接收任意类型集合
声明为 List<?> 后,集合变成“只读友好”容器。你可以安全遍历、获取元素个数、判空,但所有读出的元素都只能当作 Object 类型处理。比如:
-
for (Object item : list)—— 合法,item 是 Object,可调用 toString()、equals() 等 -
list.get(0)返回 Object,不能直接强转为 String 或 Integer(编译不报错但运行可能出错) -
list.size()、list.isEmpty()、list.clear()都可用,它们不依赖具体泛型类型
禁止写入:除 null 外一律不允许添加
向 List<?> 中 add 任何非 null 值都会触发编译错误,因为编译器无法验证你加的值是否匹配那个未知类型。例如:
-
list.add("hello")→ 编译失败 -
list.add(42)→ 编译失败 -
list.add(null)→ 唯一允许的写入操作(null 是所有引用类型的合法值)
适合场景:通用工具方法参数
当你写一个不关心元素具体类型、只做统一处理的方法时,? 最简洁安全。典型例子包括:
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- 打印集合所有内容:
public static void print(List<?> list) - 记录集合长度和清空前日志:
log("size=" + list.size()); list.clear(); - 序列化入口或统一校验(只要求非空、非 null 元素等基础检查)
注意别和 <T> 混用
List<?> 和 <T> void method(List<T> list) 不是一回事:
立即学习“Java免费学习笔记(深入)”;
- 前者表示“我完全不依赖类型”,一次适配所有 List 子类,适合纯通用操作
- 后者表示“我需要在方法内用到 T”,比如返回 T、做 instanceof 判断、或传给其他泛型方法
- 如果方法里要往集合里 add 元素,必须用
,不能用 ?

















