Java 9+ 推荐用 List.of() 创建真正不可变List,它返回JVM内置私有不可变类,禁止null、所有修改操作抛异常且反射受限;Collections.unmodifiableList仅提供不可修改视图,原List仍可被修改。

Java中创建不可变List最直接的方式是使用 Collections.unmodifiableList() 或 Java 9+ 引入的 List.of()。但二者本质不同:前者是“不可修改视图”,后者才是真正的不可变实现。
用 List.of() 创建真正不可变List(推荐,Java 9+)
List.of() 返回的是 JVM 内置的紧凑、高效、不可实例化、无公开构造器的私有不可变类(如 ImmutableCollections.ListN)。它在创建时就禁止 null 元素,且所有修改操作(add/remove/set/clear)都会抛出 UnsupportedOperationException,连反射绕过都受限(内部类无 public 构造器,且元素数组 final)。
示例:
Listlist = List.of("a", "b", "c"); list.add("d"); // 运行时抛出 UnsupportedOperationExceptionList.of(); // 空不可变ListList.of(1, 2, 3); // 支持泛型推断
用 Collections.unmodifiableList() 包装可变List(需谨慎)
该方法返回一个包装器对象,底层仍持有对原List的引用。它只是拦截修改方法,**不阻止原List被其他引用修改**——也就是说,它提供的是“只读视图”,不是“不可变性”。
立即学习“Java免费学习笔记(深入)”;
示例:
Listmutable = new ArrayList(Arrays.asList("x", "y")); Listunmod = Collections.unmodifiableList(mutable); unmod.add("z"); // 抛异常 ✅mutable.add("z"); // 原List仍可改 ❌ → unmod.size() 变为3
若要安全使用,必须确保原List不再被其他代码访问(例如封装后立即丢弃原始引用)。
第三方库方案:Guava 的 ImmutableList
Guava 提供了功能更丰富的 ImmutableList,支持 builder 模式、自定义排序、copyOf、toImmutableList() 等。其内部也使用私有不可变实现,元素在构建时深拷贝(对引用类型仅拷贝引用,非深克隆),同样拒绝 null 和修改操作。
常用写法:
ImmutableListlist = ImmutableList.of("a", "b"); ImmutableList.copyOf(array);ImmutableList.builder().add("x").addAll(otherList).build();
注意:需引入 Guava 依赖,适合已有 Guava 生态的项目。
不可变性的关键细节
真正不可变 ≠ 仅仅不能 add/remove。还需关注:
- 元素本身是否可变:若List里存的是可变对象(如 StringBuilder),即使List不可变,对象状态仍可被修改;不可变性不传递。
- 线程安全性:不可变集合天然线程安全,无需同步。
-
序列化安全:JDK 的
List.of()和 Guava 的ImmutableList都正确实现了序列化协议,反序列化后仍是不可变实例。 -
性能差异:
List.of()零内存开销(小列表甚至内联存储),unmodifiableList多一层代理对象,Guava 在构建阶段稍重但功能强。










