arrays.aslist返回的是不可变list,其底层是arrays的静态嵌套类arraylist,直接包装原数组,不支持add/remove等结构修改,调用会抛unsupportedoperationexception;所有读写操作均映射到原数组,修改一方会影响另一方。

Arrays.asList返回的是不可变List
调用Arrays.asList得到的不是java.util.ArrayList,而是Arrays内部的静态嵌套类ArrayList(注意:和java.util.ArrayList同名但不同类)。这个类直接包装原始数组,不支持结构修改。
- 它继承自
AbstractList,但没有重写add、remove、clear等方法,所以调用时会抛出UnsupportedOperationException - 所有元素读写操作都映射到原数组上——改
get(0)会真的改数组第0位,但加新元素没地方放 - 常见错误现象:
list.add("x")运行时报java.lang.UnsupportedOperationException
想增删改?必须转成真正的ArrayList
如果后续要调用add、remove或传给需要可变List的API(比如某些Spring工具类),得显式复制一份:
- 推荐写法:
new ArrayList(Arrays.asList("a", "b"))—— 安全、语义清晰、JDK 7+ - 别用
Lists.newArrayList()(Guava)除非项目已强依赖Guava;避免引入额外依赖只为绕过这个问题 - 注意性能:小列表没问题;大数组+频繁构造要留意GC压力,但通常不是瓶颈
数组类型影响结果行为
Arrays.asList对基本类型数组(如int[])的处理容易误判:
-
Arrays.asList(new int[]{1,2,3})返回的是含1个元素的List,那个元素是int[]对象本身,不是三个Integer - 只有引用类型数组(
String[]、Integer[])才能按预期拆成多个元素 - 正确写法示例:
Arrays.asList(new Integer[]{1,2,3})或用Java 5+自动装箱语法:Arrays.asList(1, 2, 3)
修改原数组会影响asList结果
因为Arrays.asList返回的List与原数组共享底层存储,这点常被忽略:
立即学习“Java免费学习笔记(深入)”;
-
String[] arr = {"a", "b"}; List<string> list = Arrays.asList(arr); arr[0] = "z";</string>→list.get(0)返回"z" - 反过来也成立:通过
set(1, "y")修改List,原数组对应位置也会变 - 如果你需要隔离,要么一开始就用
new ArrayList(...),要么复制数组:Arrays.copyOf(arr, arr.length)
add,而是有人在调试时发现List内容“莫名”变了,却没意识到背后连着一个被其他代码修改的数组。









