collections.unmodifiablemap() 返回只读视图,但底层原map修改会影响该视图;需私有化原始引用并用不可变工厂方法(如map.of、map.copyof)或深拷贝确保真正不可变。

用 Collections.unmodifiableMap() 包装即可得到只读视图,但要注意它只是“不可修改的包装器”,不是真正不可变——底层原 Map 一旦被改,只读视图也会跟着变。
基础用法:包装成只读 Map
调用 Collections.unmodifiableMap(map) 返回一个代理对象,所有修改操作(put、remove、clear、putAll)都会抛 UnsupportedOperationException:
Map<string integer> original = new HashMap();</string>original.put("a", 1);Map<string integer> readOnly = Collections.unmodifiableMap(original);</string>readOnly.put("b", 2); // ❌ 运行时报错
关键防护:切断原始引用
只调用 unmodifiableMap 不够。如果外部仍持有 original 的引用,就能继续修改它,而 readOnly 会同步看到变化:
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- 把原始 Map 声明为
private final - 不提供任何返回原始 Map 引用的 getter 方法
- getter 应始终返回
Collections.unmodifiableMap(original),而不是original
更安全的替代方案
若需彻底杜绝修改风险,推荐 JDK 9+ 的不可变工厂方法:
-
Map<string integer> immutable = Map.of("a", 1, "b", 2);</string>—— 空值或重复 key 直接编译/运行失败 -
Map<string integer> copy = Map.copyOf(original);</string>—— 创建紧凑不可变副本(要求原 Map 不含 null key/value) - Guava 用户可用
ImmutableMap.copyOf(original),支持 null 元素且构造更灵活
注意元素本身的可变性
unmodifiableMap 只禁止结构变更(增删键),不阻止 key 或 value 对象内部状态被修改。例如 value 是一个可变的自定义对象,它的字段仍可被 setter 修改。如需完全隔离,应确保 key/value 类型本身不可变,或做深拷贝。










