Java中 Collections.unmodifiableCollection 保护领域模型 Aggregate 内隐集合不被外部修改

大雪姑娘_6959

大雪姑娘_6959

2026-07-19

151人浏览

原创

collections.unmodifiablecollection仅提供只读外壳,不阻断底层集合修改;真正保护aggregate内隐集合需切断原始引用、返回副本或使用list.copyof()等不可变构造方式。

java中 collections.unmodifiablecollection 保护领域模型 aggregate 内隐集合不被外部修改

它不能真正保护 Aggregate 内隐集合不被外部修改,只提供一层“禁止调用修改方法”的表层防护。

unmodifiableCollection 是只读外壳,不是数据隔离

该方法返回的只是一个代理对象,内部仍强引用原始集合。只要 Aggregate 内部的 list 或 set 字段仍可被访问(比如通过 getter 暴露、或被其他模块持有引用),外部代码就能绕过 unmodifiableCollection 直接调用 add()、clear() 等方法——而 Aggregate 自身完全无感。

  • UnsupportedOperationException 只在你通过不可变视图调用修改方法时抛出
  • 若原始集合被第三方代码修改,视图内容实时同步变化,且不报错、不预警
  • Aggregate 的不变量(invariants)可能因此被悄然破坏,比如订单项数量与总额不一致

真正保护内隐集合,必须切断原始引用链

领域模型中 Aggregate 的内隐集合(如 Order.items、Customer.addresses)应是封装边界内的私有状态。仅包装不足够,关键在“不让原始引用逃逸”:

Release Gate
Release Gate

通过在不可逆操作前强制结构化审批,防止错误部署。可配置的检查清单,包含指定审查人员(开发、质量、法务、产品)等。

下载
  • 字段声明为 private final,构造后不再变更引用
  • 不提供返回原始集合的 getter(例如不要 public List getItems())
  • 如需对外暴露,返回新副本:return Collections.unmodifiableList(new ArrayList(items))
  • 更稳妥:在 Aggregate 构造或状态变更时,直接用 List.of(items.toArray()) 或 Set.copyOf(items) 创建不可变实例

注意嵌套可变性:子对象仍可被修改

即使 items 列表本身不可变,若其中每个 Item 是可变对象(含 setter、非 final 字段),外部仍可通过 items.get(0).setQuantity(999) 篡改状态。

  • unmodifiableList 不递归冻结元素对象
  • 若 Item 需不可变,应设计为 immutable 类(所有字段 final + 无 setter + 深拷贝构造)
  • 或在返回前做防御性复制:map(item -> new ImmutableItem(item))

推荐替代方案:JDK 10+ 的 copyOf 和 of 系列

相比 unmodifiableCollection,现代 Java 提供更可靠的原生不可变构造方式:

  • List.copyOf(items) —— 自动判空、去 null、返回真正不可变 List,且不保留对原集合引用
  • Set.copyOf(items) —— 自动去重并冻结,比 unmodifiableSet 安全得多
  • List.of(e1, e2) 或 List.of(items.toArray()) —— 创建紧凑、不可变、拒绝 null 的实例
  • 注意:of 系列要求元素非 null,且 List.of() 最多 10 个元素;超限时用 List.copyOf()

不复杂但容易忽略:保护 Aggregate 内隐集合,核心不在“加锁”或“包装”,而在“封装意识”——让集合成为真正的私有实现细节,而非可传递的共享引用。

Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

2023.06.15

11197

6

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

2023.07.05

8302

9

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

2023.07.31

7172

8

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.01

1204

3

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.02

968

3

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

1436

5

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

2949

5

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

2023.08.03

20211

3

配置java环境变量
配置java环境变量

配置Java环境变量是为了让操作系统能够识别和使用Java的相关命令和功能。本专题为大家提供配置java环境变量相关文章,帮助大家解决问题。

2023.08.03

1295

8

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
dev.java 官方:Learn Java
dev.java 官方:Learn Java

共0课时 | 0人学习

Java JDBC数据库连接官方教程
Java JDBC数据库连接官方教程

共0课时 | 0人学习