Collections.emptyList() 返回不可变、类型安全、内存共享的单例空List实例,避免NPE且零分配;适用于只读场景,修改会抛UnsupportedOperationException。

为什么 Collections.emptyList() 能替代 null 返回值
直接返回 null 的集合,调用方必须反复判空,一漏就抛 NullPointerException。而 Collections.emptyList() 返回的是一个**不可变、类型安全、内存共享的空 List 实例**——它不是 null,长度为 0,且所有操作(如 size()、isEmpty()、iterator())都合法,不会触发 NPE。
关键点在于:这个实例是单例(JDK 内部缓存),无论调用多少次 Collections.emptyList(),返回的都是同一个对象,不额外分配内存。
什么时候该用 Collections.emptyList() 替代 new ArrayList()
两者都返回空列表,但语义和性能不同。用 Collections.emptyList() 更合适的情况包括:
- 方法契约明确“只读”或“永不修改”,比如 DAO 层查询无结果时的默认返回
- 频繁调用的工具方法(如配置解析、枚举转换),避免每次新建对象带来的 GC 压力
- 泛型类型已知(如
Collections.<string>emptyList()</string>),需保持与返回值声明类型一致 - 你不需要后续
add()、remove()等可变操作——否则会抛UnsupportedOperationException
如果业务逻辑后续一定会往列表里加元素,那就别硬套 emptyList(),老实用 new ArrayList()。
Collections.emptyList() 的典型误用和报错
最常见错误是忽略其不可变性,试图修改它:
List<String> list = Collections.emptyList();
list.add("foo"); // 抛出 UnsupportedOperationException
另一个隐蔽坑是类型擦除导致的编译警告或运行时问题:
- 写成
Collections.emptyList()(没带泛型)→ 返回原始类型List,可能引发 unchecked 警告 - 正确写法必须显式指定类型参数:
Collections.<integer>emptyList()</integer>或配合目标类型推导(如赋值给List<integer></integer>变量时可省略) - 在泛型方法中直接返回
Collections.emptyList()而不绑定类型,会导致调用方收到List<object></object>,不是预期类型
替代方案对比:Guava 的 ImmutableList.of() 和 JDK 9+ List.of()
它们都能创建不可变空列表,但行为有差异:
-
Collections.emptyList():零分配、单例、JDK 1.2 就有,兼容性最好 -
ImmutableList.of()(Guava):也单例空实例,但需引入 Guava;非空时才真正构建对象 -
List.of()(JDK 9+):空列表调用List.of()会返回一个专用空实例(也是单例),但注意List.of()不接受null元素——而emptyList()没这限制
如果你的项目已用 JDK 9+ 且无需支持更老版本,List.of() 是更现代的选择;否则,Collections.emptyList() 仍是稳妥首选——尤其要注意它不抛异常、不分配、不挑 JDK 版本。

















