应优先返回 collections.emptylist() 而非 null:它提供真实、不可变、线程安全的空 list 实例,避免 npe,简化调用方判空逻辑,语义更清晰(“结果为空”≠“未定义”),且无额外内存开销。

空集合能直接调用方法,null 会立即崩溃
返回 Collections.emptyList() 得到的是一个真实存在的、不可变的 List 实例;调用 isEmpty()、size()、forEach() 或 stream() 都不会出错。而返回 null 后,只要调用任何方法(如 list.size()),就会触发 NullPointerException,导致程序中断。
调用方无需写防御性判空,代码更简洁安全
如果接口统一返回空集合,使用者可以直接遍历或链式操作:
list.stream().map(...).collect(Collectors.toList())for (String s : list) { ... }if (list.isEmpty()) { ... }
不需要在每处都加 if (list != null),避免漏判、嵌套深、逻辑冗余,也减少因疏忽引入的 bug。
语义清晰:“无数据”不等于“未定义”
null 表示“该值不存在”或“计算未完成”,常用于异常路径、未初始化字段或失败的查找;而空集合明确表达“查询成功,结果确实为空”。例如:
- 用户权限列表查无记录 → 返回
Collections.emptyList()(存在但为空) - 数据库连接失败导致无法查询 → 才考虑抛异常或返回
null(操作未完成)
这种区分让 API 更易理解、更符合直觉。
性能开销极小,且有优化方案
Collections.emptyList() 是静态 final 实例,复用同一个对象,不产生额外 GC 压力;相比每次 new ArrayList(),它内存零分配、线程安全、序列化友好。即使在高并发场景下,也不会因共享导致状态混乱——因为它是不可变的。
若业务需要可变集合,再按需新建(如 new ArrayList(0)),但绝大多数只读场景,emptyList() 就是最优解。










