Arrays.asList 返回的是不可变结构的 List,底层为 Arrays 的静态内部类,不支持 add/remove/clear 等操作,调用即抛 UnsupportedOperationException;无 modCount,故无 fail-fast 机制。

Java 中 Arrays.asList 返回的 List 对象虽然类型是 ArrayList,但它并不是 java.util.ArrayList,而是 Arrays 类的一个静态内部类(通常叫 ArrayList,但注意不是 java.util.ArrayList),它**不支持结构修改操作**,因此 fail-fast 机制在它身上表现得更“刚性”——不是“检测到并发修改后抛异常”,而是**调用 add/remove/clear 等方法时直接抛 UnsupportedOperationException,根本走不到 modCount 检查那一步。
Arrays.asList 返回的是不可变结构的 List
这个 List 是数组的“视图”,底层仍指向原数组,所有写操作都被禁止:
-
add()、remove()、clear()、retainAll()等会立即抛UnsupportedOperationException - 没有
modCount字段,所以不存在迭代器的 expectedModCount 校验逻辑 - 它的迭代器(
Iterator)也是只读的:调用iterator.remove()同样抛UnsupportedOperationException
单线程下不会触发 ConcurrentModificationException
因为结构无法被修改,自然不会有“遍历时被其他代码改了”的情况:
- 即使你在 for-each 或 iterator 遍历中试图调用
list.add(),也早在执行前就失败了,不会进入迭代器的 checkForComodification 流程 - 不存在多线程竞争导致的 modCount 不一致问题——连单线程都不让改,何谈并发修改
想用真正的 fail-fast 行为?得先转成 java.util.ArrayList
如果你需要可修改 + fail-fast 的行为(比如测试 ConcurrentModificationException),必须显式拷贝:
立即学习“Java免费学习笔记(深入)”;
List<string> mutable = new ArrayList(Arrays.asList("a", "b", "c"));</string>- 这时
mutable是标准的java.util.ArrayList,有modCount,迭代中调用remove()就会触发 fail-fast(抛ConcurrentModificationException) - 同理,若用于多线程场景,仍需换成
CopyOnWriteArrayList或加锁等方案
常见误区:以为 Arrays.asList 返回的就是 java.util.ArrayList
这是最典型的混淆点:
- 二者类名相同(都叫
ArrayList),但包路径不同:java.util.Arrays$ArrayListvsjava.util.ArrayList - 前者是轻量级适配器,后者是完整实现;前者无扩容、无 modCount、无 fail-fast 逻辑
- IDE 或 toString() 输出可能都显示
[a, b, c],容易误判,但行为截然不同


















