Arrays.asList 返回的是不可变的 Arrays$ArrayList 视图,不支持增删操作,基本类型数组会整体入列,且与原数组共享引用;需可变列表时须用 new ArrayList<>(asList()) 显式拷贝。

Arrays.asList 是 Java 中最常用的数组转 List 工具,但不是“万能转换器”——它返回的是不可变视图,不支持增删,基本类型数组会整体入列,且与原数组共享数据。用对场景高效省资源,用错一行代码就抛异常。
它返回的不是 ArrayList
Arrays.asList 返回的是 java.util.Arrays$ArrayList(Arrays 的私有内部类),不是 java.util.ArrayList。这个类继承 AbstractList,只实现了 get/set/contains/size 等读取和替换操作,但没重写 add/remove/clear —— 所以调用就会抛 UnsupportedOperationException。
- 打印 list.getClass() 会看到:
class java.util.Arrays$ArrayList - 它实现了 RandomAccess 和 Serializable,适合快速随机访问和序列化
- 它的 size 固定等于原始数组长度,无法扩容或缩容
基本类型数组必须绕开
传 int[]、double[] 等进去,不会自动拆箱,而是把整个数组当做一个 Object 元素塞进 List,结果是 size=1 的 List<int[]>,极易引发逻辑错误。
- ❌ 错误写法:
int[] arr = {1,2,3}; List<int[]> list = Arrays.asList(arr); - ✅ 正确写法(包装类数组):
Integer[] boxed = {1,2,3}; List<Integer> list = Arrays.asList(boxed); - ✅ 正确写法(Stream 装箱):
List<Integer> list = Arrays.stream(arr).boxed().collect(Collectors.toList());
数组与 List 共享底层引用
Arrays.asList 返回的是原数组的“适配器视图”,set 操作会直接改原数组,改原数组也会实时反映在 List 上。
立即学习“Java免费学习笔记(深入)”;
- String[] arr = {"a", "b"}; List<String> list = Arrays.asList(arr);
- list.set(0, "x"); → arr[0] 变成 "x"
- arr[1] = "y"; → list.get(1) 返回 "y"
- 多线程环境下需额外同步,否则可能数据不一致
需要可变列表?必须显式拷贝
只要后续要 add/remove/传给框架 setter/做结构性操作,就不能直接用 asList 结果,必须包装一层。
- 推荐写法:
List<String> mutable = new ArrayList<>(Arrays.asList("a", "b")); mutable.add("c"); - Java 10+ 可用
List.copyOf(Arrays.asList(...)),但它仍返回不可变 List,不解决可变需求 - 若已有空 ArrayList,可用
Collections.addAll(list, arr)避免中间对象


















