Arrays.asList() 返回的是不可变结构的数组视图,支持 get、set、contains 等操作,但 add、remove 等修改结构的操作会抛 UnsupportedOperationException;需用 new ArrayList(Arrays.asList(arr)) 转为可变集合。

因为 Arrays.asList() 返回的不是 java.util.ArrayList,而是一个固定大小的“视图列表”——java.util.Arrays$ArrayList,它直接绑定原始数组,不支持改变结构的操作。
底层是数组视图,不是可变集合
这个内部类(Arrays$ArrayList)持有一个 final E[] a 引用,完全复用原数组的内存空间。它的 size() 就是数组长度,无法扩容或缩容。调用 add() 时,由于该类未重写 add() 方法,会继承 AbstractList.add() 的默认实现:
public void add(int index, E element) { throw new UnsupportedOperationException(); }- 这是 JDK 明确设计的限制,不是 bug,目的是保证“列表结构 = 数组结构”严格一致
哪些操作能用?哪些不能?
允许的操作(只读或原地更新):
-
get()、size()、contains()、indexOf() -
set(index, e):可以修改已有位置的值,且会同步改写原数组对应元素 -
toArray():返回原数组的克隆,不破坏原数组
禁止的操作(改变结构或大小):
-
add()、addAll()、remove()、clear()、retainAll() - 哪怕只是
list.add("x"),也会在运行时报UnsupportedOperationException
想增删?必须创建新实例
不能绕过限制,也不能用 Collections.unmodifiableList() 或反射“修复”。正确做法是立即包装成真正的可变集合:
-
推荐:
new ArrayList(Arrays.asList(arr))—— 安全、语义清晰、兼容所有 JDK 版本 - Java 8+ 可选:
Arrays.stream(arr).collect(Collectors.toList())(注意:JDK 16+ 中Collectors.toList()仍返回可变ArrayList) - 避免使用
List.copyOf()(Java 10+),它返回的是不可变集合,同样不支持add
一个小陷阱:set() 会影响原数组
例如:
String[] arr = {"a", "b"};List<string> list = Arrays.asList(arr);</string>-
list.set(0, "x");→ 此时arr[0]已变为"x"
这不是副作用,而是设计本意:它是数组的实时双向视图——能改值,但不能改长度。

















