Arrays.asList返回的是共享原数组内存、固定大小的视图列表,支持set/contains等操作但不支持add/remove;需可变列表时应创建独立副本,如new ArrayList(Arrays.asList(arr))。

Arrays.asList 返回的不是普通 ArrayList,而是一个与原数组共享内存、双向联动、固定大小的视图列表。它轻量高效,但不支持增删——这不是 bug,而是设计契约。
它和原数组是“同一块内存”
Arrays.asList 返回的内部类直接持有原始数组引用,所有 set() 或直接改数组元素都会实时同步:
- 调用
list.set(0, "x")→ 原数组arr[0]立即变成 "x" - 手动改
arr[1] = "y"→list.get(1)马上返回 "y" - 两者
size()始终相等,且无法 add/remove 改变长度
为什么调用 add 就报错?
它底层是 java.util.Arrays.ArrayList(私有静态类),继承自 AbstractList,但没重写 add/remove/clear 等结构性方法——这些方法默认抛 UnsupportedOperationException:
-
list.add("new")→ 直接崩溃 -
list.remove(0)→ 同样抛异常 - 但
list.set(0, "ok")、list.contains("a")、list.indexOf("b")全部正常
需要可变列表?必须主动解耦
想后续 add/remove/sort/传给框架 setter?不能依赖视图,得创建独立副本:
立即学习“Java免费学习笔记(深入)”;
- 中小数据量:用
new ArrayList(Arrays.asList(arr))——语义清晰、兼容性好 - 大数据量(上万):预分配容量 +
Collections.addAll(list, arr),跳过中间视图,更省内存 - 基本类型数组(如
int[])要先装箱:Arrays.stream(nums).boxed().collect(Collectors.toList())
别踩这三个常见坑
很多问题就出在没看清类型和行为:
- 把
int[]{1,2,3}直接传入 → 得到的是List<int></int>(只有 1 个元素),不是三个 Integer - 误以为返回的是
java.util.ArrayList→ 结果调 add 时才发现报错 - 修改 list 后又继续用原数组 → 因为联动,可能引发意料外的数据污染


















