Arrays.asList()返回的不是java.util.ArrayList,而是Arrays内部的固定大小List视图(Arrays$ArrayList),底层直接引用原数组,不支持add/remove等结构性修改,调用会抛UnsupportedOperationException;但允许get、set、size等查询及元素更新操作,且set会同步影响原数组。
arrays.aslist() 返回的不是真正的 arraylist,而是一个内部定义的、继承自 abstractlist 的“固定大小列表”(arrays.arraylist,注意:这不是 java.util.arraylist)。它底层直接包装原始数组,不支持增删操作——调用 add()、remove()、clear() 等会直接抛出 unsupportedoperationexception。
为什么 add() 会报错?关键在底层实现
这个“受限列表”的 add() 方法直接继承自 AbstractList,而后者默认实现就是抛异常:
它没有重写该方法,也不持有可扩容的存储结构(比如动态数组),因为背后是普通 Java 数组,长度固定、无法插入新元素。
哪些操作被限制?哪些仍可用?
- 禁止的操作:add()、addAll()、remove()、removeAll()、retainAll()、clear()、set()(仅当索引越界时才报错,但 set() 本身是允许的——它只是改原数组对应位置的值)
- 允许的操作:get()、set()(合法索引)、size()、contains()、indexOf()、iterator()、toArray(),以及所有不改变结构的查询类方法
如何安全地转成可修改的 List?
如果后续需要增删,必须显式创建一个真正可变的副本:
- 推荐方式:new ArrayList(Arrays.asList(...)) —— 利用构造器复制元素到新的动态数组中
- 其他等效写法:new LinkedList(Arrays.asList(...)),或用 Stream(Java 8+):Arrays.stream(arr).collect(Collectors.toList())
- 注意:不要写成 List.copyOf(Arrays.asList(...)),它返回的是不可变集合(Java 10+),同样不支持修改
一个小陷阱:修改“受限列表”会影响原数组
因为它是原数组的视图,调用 set(i, x) 会直接改写原数组第 i 个位置的值。例如:
List
list.set(0, "x");
// 此时 arr[0] 已变成 "x"
这是“受限”但“实时绑定”的体现——不支持增删,却能更新已有元素,且双向可见。

















