# 22. 为什么 Arrays.asList() 生成的 List 不能进行 add/remove 操作?

# 标准答案

Arrays.asList() 生成的 List 本质上是 java.util.Arrays.ArrayList(内部类),它并不是 java.util.ArrayList,而是基于数组的固定大小 List。该 List 仅是原数组的视图(View),不支持增删元素,但支持修改已有元素。

这背后的原因是:

  1. Arrays.asList() 直接使用原数组作为底层存储,无法动态扩展或收缩
  2. add() / remove() 需要调整内部存储(如扩容或缩容),但 Arrays.ArrayList 只是包装了原数组,无法真正改变数组大小,因此抛出 UnsupportedOperationException

如果需要支持增删操作,应使用 new ArrayList<>(Arrays.asList(...)) 进行拷贝。

# 答案解析

# 1. Arrays.asList() 返回的 List 实现类

List<Integer> list = Arrays.asList(1, 2, 3);
System.out.println(list.getClass()); // class java.util.Arrays$ArrayList
1
2

Arrays.asList() 返回的是 java.util.Arrays.ArrayList(内部类),而不是 java.util.ArrayList

# 2. 为什么 add/remove 会抛异常?

执行以下代码:

List<Integer> list = Arrays.asList(1, 2, 3);
list.add(4); // UnsupportedOperationException
list.remove(1); // UnsupportedOperationException
1
2
3

会抛出:

Exception in thread "main" java.lang.UnsupportedOperationException
1

原因是 ArrayListArrays.ArrayList 的内部类)没有实现 add()remove(),其 size 直接来自底层数组,数组大小固定,无法增删。

# 3. Arrays.ArrayList 内部结构

源码(JDK 8):

private static class ArrayList<E> extends AbstractList<E> 
    implements RandomAccess, java.io.Serializable {
    final E[] a; // 持有的数组

    ArrayList(E[] array) {
        a = Objects.requireNonNull(array);
    }

    public E get(int index) {
        return a[index]; // 直接访问数组
    }

    public E set(int index, E element) {
        E oldValue = a[index];
        a[index] = element; // 允许修改原数组
        return oldValue;
    }

    public int size() {
        return a.length; // 大小固定
    }

    public void add(int index, E element) {
        throw new UnsupportedOperationException(); // 不支持插入
    }

    public E remove(int index) {
        throw new UnsupportedOperationException(); // 不支持删除
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

可以看到:

  • get() 直接访问 a[index]允许读取
  • set() 直接修改 a[index]允许修改
  • add() / remove() 直接抛出 UnsupportedOperationException不允许增删

# 4. 如何正确使用 Arrays.asList()

# 方法 1:用 new ArrayList<>() 复制
List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3));
list.add(4); // 可正常添加
System.out.println(list); // [1, 2, 3, 4]
1
2
3
# 方法 2:使用 List.of()(JDK 9+,不可变)
List<Integer> list = List.of(1, 2, 3);
list.add(4); // UnsupportedOperationException
1
2

List.of() 生成的 List 完全不可变set() 也不允许。

# 方法 3:使用 ArrayList.copyOf()(JDK 10+,不可变)
List<Integer> list = List.copyOf(Arrays.asList(1, 2, 3));
1

返回的 List 也是不可变的,避免误用。

# 深入追问

  • Arrays.asList()List.of() 在不可变性上有何不同?
  • 为什么 set() 允许,但 add() / remove() 不允许?
  • Arrays.asList() 为什么不会影响原数组?

# 相关面试题

  • List.of()Arrays.asList() 的区别?
  • Collections.unmodifiableList()List.copyOf() 的区别?
  • 为什么 Arrays.asList() 返回的 List 不能序列化?