最稳妥方式是从源头避免null,用collections.emptylist()等不可变空集合替代null返回值;调用方可安全操作,无需判空;若需修改则显式复制为arraylist。

Java中处理可能为null的集合,最稳妥的方式不是“先判空再操作”,而是从源头避免null出现——用Collections.emptyList()等不可变空集合替代null返回值。
用 emptyList() 替代 null 返回值
方法签名明确承诺返回List<t></t>时,就绝不应返回null。否则调用方每次都要写if (list != null),既冗余又易遗漏。
- ✅ 正确做法:直接返回
Collections.<string>emptyList()</string>(Java 7需显式泛型)或Collections.emptyList()(Java 8+多数场景可省略) - ✅ 调用方可安全调用
size()、isEmpty()、stream()、增强for循环,无需任何判空 - ❌ 不要返回
null,也不要返回new ArrayList()——后者虽可变但有无谓对象开销
旧代码中批量转换潜在 null 集合
对接遗留DAO或第三方接口时,常遇到可能返回null的集合。可在服务封装层统一兜底:
- 写一个泛型工具方法:
private <t> List<t> nullToEmpty(List<t> list) { return list == null ? Collections.emptyList() : list; }</t></t></t> - 在业务方法中直接包裹:
return nullToEmpty(legacyDao.queryUsers(id)); - 这样下游永远拿到的是“有对象、非null、可安全操作”的集合,契约清晰
注意不可变性带来的行为边界
Collections.emptyList()返回的是只读单例,设计上就拒绝修改:
- ✅ 支持:
isEmpty()、size()、stream()、forEach()、contains() - ❌ 禁止:
add()、remove()、set()—— 会立即抛UnsupportedOperationException - ⚠️ 若后续逻辑确实需要添加元素,必须显式复制:
new ArrayList(Collections.emptyList())
慎用 Optional 混搭 emptyList
Optional适合表达“值可能存在也可能不存在”的语义,而emptyList()已明确表达了“存在,且为空”。两者目标不同:
- ❌ 不推荐:
Optional.ofNullable(list).orElse(Collections.emptyList())—— 多此一举,掩盖了本可消除的null路径 - ✅ 更优解:上游改造成稳定返回
emptyList(),下游彻底告别Optional包装和orElse判断 - ? 例外:仅当无法修改上游(如调用外部SDK),且你仅需临时转流时,才用
Optional.ofNullable(list).map(Collection::stream).orElse(Stream.empty())
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











