collections.unmodifiablelist返回运行时不可修改的列表视图,支持读操作但拦截写操作并抛unsupportedoperationexception;它不是深拷贝,原列表修改会反映在视图中,需先复制再包装才能隔离变更。

使用 Collections.unmodifiableList 可以快速包装一个已有 List,返回一个**运行时不可修改**的视图。它不是深拷贝,也不阻止原列表被修改,只是对返回的包装对象加了写操作拦截。
基本用法:包装已有 List
传入一个非 null 的 List(如 ArrayList、LinkedList),得到一个只读的 List:
List<string> original = new ArrayList(Arrays.asList("a", "b", "c"));
List<string> readOnly = Collections.unmodifiableList(original);
</string></string>
此时 readOnly 支持 get()、size()、contains()、遍历等读操作,但任何修改操作(如 add()、set()、remove()、clear())都会立即抛出 UnsupportedOperationException。
注意:原列表仍可变,只读视图会同步反映变化
unmodifiableList 返回的是原列表的“只读门面”,不是副本。如果后续修改了 original,readOnly 的内容也会变:
original.add("d");
System.out.println(readOnly); // [a, b, c, d] —— 会看到新元素
若需要真正隔离,应先复制再包装:
- 用
new ArrayList(original)创建副本 - 再用
Collections.unmodifiableList(...)包装副本
结合泛型和类型安全使用
推荐直接声明为 final 和具体泛型类型,避免意外赋值或类型擦除问题:
final List<integer> numbers = Collections.unmodifiableList(
Arrays.asList(1, 2, 3)
);
// numbers = new ArrayList(); // 编译错误(final)
// numbers.add(4); // 运行时异常
</integer>
注意:Arrays.asList() 返回的列表本身是固定大小的(add/remove 也会抛异常),再套一层 unmodifiableList 是为了统一语义和防御性编程。
替代方案:Java 10+ 推荐用 List.of()(更简洁、不可变且不可空)
如果不需要支持 null 元素,且数据在编译期已知或可一次性构造,优先用:
List<string> safe = List.of("x", "y", "z"); // 不可修改、不可含 null、线程安全
</string>
它的底层实现更轻量,且明确禁止 null;而 unmodifiableList 允许原列表含 null,只限制写操作。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











