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