Arrays.asList() 返回的是不可变List,其底层是Arrays的静态内部类,直接包装原始数组,不支持add/remove等操作,调用会抛UnsupportedOperationException;它与java.util.ArrayList同名但不同类。
Arrays.asList 返回的是不可变 List
调用
得到的不是
,而是
内部的静态嵌套类
(注意:和
同名但不同类),它直接包装原始数组,不支持增删操作。一旦调用
、
或
,会抛出
。
常见错误现象:
运行时报错
适用场景:仅需只读访问、快速初始化、配合
显式强调不可变语义
根本原因:该内部类未重写父类(
)的结构性修改方法,所有修改操作默认抛异常
基本用法与泛型陷阱
接收可变参数(
),所以传入基本类型数组(如
)时,整个数组会被当作单个元素处理,导致结果是包含一个
的单元素列表,而非你预期的多个
元素。
正确写法(对象数组):
→ 3 元素
错误写法(基本类型数组):
→ 1 元素
补救方式:先转为包装类型数组,例如用
(Java 8+),或手动构造
需要可变 List?必须显式拷贝
如果后续要
、
或传给要求可变
的 API(如某些框架的 setter),必须用可变实现类包装原始结果。
推荐做法:
—— 简洁、通用、无歧义
替代写法(Java 10+):
,但注意它仍返回不可变 List
性能提示:拷贝有 O(n) 开销,若只是临时遍历或传参,跳过拷贝更高效
注意点:
中的
必须是对象数组;若源是基本类型数组,得先完成装箱转换
原始数组与 List 共享底层引用
返回的 List 是原始数组的“视图”,对 List 的
操作会直接修改原数组,反之亦然。
示例:
→
变成
影响:若原数组后续还会被其他代码使用,这种隐式联动容易引发 bug
规避方式:如不需要联动,优先走
拷贝路径;如需联动且只读,用
封装返回值,避免误改
原始数组与 List 的引用绑定关系最容易被忽略——它既不是完全隔离,也不是彻底独立,而是一种“浅层共享”。要不要打破它,取决于你是否信任调用方不会意外修改原数组。
Arrays.asList()ArrayListArraysArrayListjava.util.ArrayListadd()remove()clear()UnsupportedOperationExceptionlist.add("x")java.lang.UnsupportedOperationExceptionCollections.unmodifiableList()AbstractListArrays.asList()T... aint[]int[]IntegerArrays.asList("a", "b", "c")ListArrays.asList(new int[]{1,2,3})ListStream.of(arr).boxed().collect(Collectors.toList())Integer[]addremoveListnew ArrayList<>(Arrays.asList(arr))List.copyOf(Arrays.asList(arr))new ArrayList<>(Arrays.asList(arr))arrArrays.asList()set()String[] arr = {"a", "b"}; List list = Arrays.asList(arr); list.set(0, "x"); arr[0]"x"new ArrayList<>()Collections.unmodifiableList()