在 getter 中使用 Collections.unmodifiableList 是为了防止外部修改内部列表,保障封装性;它返回只读视图,修改操作抛 UnsupportedOperationException,且无需复制元素,每次调用应重新包装以确保同步。

直接在 getter 中返回 Collections.unmodifiableList 包装后的列表,能防止外部修改内部状态,这是保护集合属性的常用做法。
为什么要在 getter 里用 unmodifiableList?
Java 中 List 是可变对象,如果 getter 直接返回原始 list(比如 return this.items;),调用方就能通过 add/remove/clear 等操作意外改变类的内部数据,破坏封装性。用 unmodifiableList 返回一个只读视图,任何修改操作都会抛出 UnsupportedOperationException,既安全又轻量(不复制元素)。
标准写法:每次 getter 都包装一次
不要缓存包装后的 list(除非确定 list 内容永不变更且性能敏感),因为原始 list 变化后,缓存的不可变视图不会自动同步。推荐每次调用 getter 都重新包装:
private List<String> items = new ArrayList<>();
public List<String> getItems() {
return Collections.unmodifiableList(items);
}
配合初始化和 setter 的完整实践
为了真正安全,还需注意两点:一是避免在构造或 setter 中传入外部可变 list;二是 setter 应该做防御性拷贝:
立即学习“Java免费学习笔记(深入)”;
- 构造方法中用
new ArrayList(input)或List.copyOf(input)(Java 10+)复制传入的 list - setter 中也应先拷贝再赋值,例如:
this.items = new ArrayList(newItems); - getter 始终返回
Collections.unmodifiableList(this.items)
替代方案:用不可变集合库(如 Guava 或 Java 10+)
如果项目允许,更推荐用 ImmutableList(Guava)或 List.of()/List.copyOf() 初始化不可变 list,从源头杜绝可变性。但若已有可变 list 字段,getter 加 unmodifiableList 仍是简单有效的补救方式。


















