collections.unmodifiablelist返回原集合的只读代理而非新集合,读操作委托原列表,写操作抛unsupportedoperationexception;它不复制数据,故原集合改动会实时反映在视图中。

Collections.unmodifiableList 返回的不是新集合,而是原集合的只读代理——改原集合,视图立刻变;试图修改视图,直接抛 UnsupportedOperationException。
为什么调用后还能看到原集合的改动
它不复制数据,只是套了一层拦截逻辑。所有读操作(get、size、iterator)委托给原始 List,写操作(add、set、clear)一律拒绝。
- 常见错误现象:对返回的“只读列表”调用
add报错java.lang.UnsupportedOperationException - 但若你保留了原始
ArrayList引用,并在别处add了元素,unmodifiableList视图里立刻能get到新元素 - 使用场景:适合做 API 返回值封装,防止调用方误改,但无法防住内部其他代码改原集合
怎么真正隔离修改风险
如果要彻底切断外部和内部对数据的修改能力,必须在包装前冻结源头。
- 最稳妥做法:先用
new ArrayList(original)或List.copyOf(original)(Java 10+)创建不可变副本,再套Collections.unmodifiableList - 注意
List.copyOf要求入参非null且不含null元素,否则抛NullPointerException - 如果原始集合本身是线程不安全的,且多线程并发读写,仅加
unmodifiableList不解决竞态问题
和 List.of / Arrays.asList 的关键区别
三者都常被当作“只读列表”用,但行为差异很大:
-
Arrays.asList返回的是固定长度的List,支持set,但不支持add/remove;底层仍直连原始数组 -
List.of(Java 9+)是真正不可变的:不基于原集合,也不允许set,且序列化安全、线程安全 -
Collections.unmodifiableList是运行时防护层,依赖原始集合生命周期;若原始集合被回收或重置,视图可能失效或抛NullPointerException
真正安全的只读视图,得看源头是否可控、是否需要深隔离。用 unmodifiableList 前,先问自己:这个原始 List 还有别的引用吗?别人会不会偷偷改它?










