应使用 Collections.emptyList() 替代 null 返回空集合,因其是不可变、类型安全、轻量级的静态单例,调用方无需判空即可安全操作;但需显式指定泛型类型,且不可执行 add 等修改操作。

为什么用 Collections.emptyList() 替代 null 返回空集合
直接返回 null 给调用方,等于把空指针风险甩锅出去;而 Collections.emptyList() 返回的是一个不可变、类型安全、轻量级的空 List,调用方能直接遍历、调用 size()、isEmpty(),完全不用判空。它底层是静态单例,不分配新对象,也没有同步开销。
Collections.emptyList() 的泛型必须显式指定
Java 7+ 中编译器常无法从上下文推断泛型类型,直接写 Collections.emptyList() 可能导致类型擦除后变成原始 List,引发编译警告或运行时 ClassCastException。尤其在方法返回值为泛型接口(如 List)时更明显。
正确写法必须带类型参数:
List<string> getNames() {
return Collections.<string>emptyList();
// 或 Java 8+ 更简洁写法:
// return Collections.emptyList();
}</string></string>
注意:Java 8 起在多数上下文中可省略类型参数,但遇到重载方法、泛型通配符(如 ? extends Number)或 IDE 检查严格时,仍建议显式写出。
别把它当普通 ArrayList 用
Collections.emptyList() 返回的是私有静态内部类(如 EmptyList),所有修改操作(add、remove、set)都会抛出 UnsupportedOperationException。这不是 bug,是设计使然 —— 它只承诺“空”和“不可变”。
- ✅ 安全操作:
isEmpty()、size()、stream()、forEach() - ❌ 危险操作:
list.add("x")→ 立刻抛UnsupportedOperationException - ⚠️ 注意场景:若业务逻辑后续需要往这个 list 添加元素,必须先复制成可变集合,例如:
new ArrayList(Collections.emptyList())
对比 Arrays.asList() 和构造器创建空集合
有人误用 Arrays.asList() 或 new ArrayList() 代替,但这俩有本质区别:
-
Arrays.asList()返回固定大小列表,add/remove同样抛异常,且不支持泛型推断(易错) -
new ArrayList()每次都新建对象,有内存与 GC 开销;而Collections.emptyList()是全局唯一实例 - Spring、MyBatis 等框架的泛型注入/反射解析,对
Collections.emptyList()兼容性更好,对空构造器集合有时会因类型擦除失败
真正要注意的是:一旦你选了 Collections.emptyList(),就得接受它的不可变契约——不是所有“空集合”都该被当成“可写容器”的占位符。










