登录
首页 >  文章 >  java教程

不可变集合是什么?Java安全集合解析

时间:2026-02-09 20:48:40 279浏览 收藏

今日不肯埋头,明日何以抬头!每日一句努力自己的话哈哈~哈喽,今天我将给大家带来一篇《不可变集合是什么?Java集合安全设计解析》,主要内容是讲解等等,感兴趣的朋友可以收藏或者有更好的建议在评论提出,我都会认真看的!大家一起进步,一起学习!

Java不可变集合指由Collections.unmodifiableXXX()或JDK 10+ ImmutableCollections生成、运行时抛UnsupportedOperationException的实例;它非只读视图,也不等价线程安全,仅拦截写操作,底层引用仍可被修改。

在Java里不可变集合是什么_Java集合安全设计说明

不可变集合在Java里到底指什么

Java里的不可变集合(Immutable Collection)不是“不能修改”的接口或抽象概念,而是明确由Collections.unmodifiableXXX()java.util.ImmutableCollections(JDK 10+ 内部实现)生成的、运行时抛出UnsupportedOperationException的实例。它不等于“只读视图”,更不等于“线程安全”——只是把写操作拦截掉,底层引用仍可能被其他可变集合改写。

怎么创建真正安全的不可变集合

Collections.unmodifiableList()这类包装器是常见误区:它只保护包装层,原始集合一旦被修改,不可变视图也会变。要真正安全,必须确保源头不可变:

  • 优先使用List.of()Set.of()Map.of()(JDK 9+),它们返回的是紧凑、不可变、非空、无null的实例
  • 若需含null或动态构建,用ImmutableList.copyOf()(Guava)或new ArrayList(source).unmodifiable()(JDK 14+ Collection.copyOf()
  • 避免用Arrays.asList()再套unmodifiableList():前者返回的仍是可变数组-backed 列表

不可变集合和并发安全的关系

不可变集合天然线程安全,但仅限于“自身状态不被修改”。它不解决以下问题:

  • 如果集合元素本身是可变对象(比如ListPerson字段可变),整体仍不安全
  • 不可变集合不保证构造过程的原子性;多线程同时调用List.of(a, b, c)没问题,但若a/b/c来自共享可变状态,需额外同步
  • Stream.toList()(JDK 16+)返回的是不可变列表,但前提是stream源本身稳定

遇到UnsupportedOperationException该怎么查

这个异常几乎只说明一点:你误把不可变集合当可变用了。典型场景包括:

  • Set.of("a", "b")调用add()remove()
  • 从Spring配置或Jackson反序列化得到一个集合,但框架默认返回不可变类型(如LinkedHashSet被替换为不可变实现)
  • MyBatis查询结果被自动包装成不可变List(某些版本或配置下)

排查时直接搜at java.base/java.util.ImmutableCollections$AbstractImmutableCollection.add堆栈,定位哪行代码试图修改。

真正麻烦的从来不是“怎么建不可变集合”,而是搞清谁持有它的可变副本、元素是否真不可变、以及上下游框架是否悄悄替换了实现。

本篇关于《不可变集合是什么?Java安全集合解析》的介绍就到此结束啦,但是学无止境,想要了解学习更多关于文章的相关知识,请关注golang学习网公众号!

前往漫画官网入口并下载 ➜
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>