星星之火-Arrays.asList()的UnsupportedOperationException异常坑

本文最后更新于:July 16, 2023 pm

积土成山,风雨兴焉;积水成渊,蛟龙生焉;积善成德,而神明自得,圣心备焉。故不积跬步,无以至千里,不积小流无以成江海。齐骥一跃,不能十步,驽马十驾,功不在舍。面对悬崖峭壁,一百年也看不出一条裂缝来,但用斧凿,能进一寸进一寸,能进一尺进一尺,不断积累,飞跃必来,突破随之。

目录

今天写项目自测的过程中发现Arrays.asList()的一个小坑,特此记录。

实例代码

1
2
3
4
5
public static void main(String[] args) {
List<String> list = Arrays.asList("a", "b", "c");
list.add("d");

}

在运行上述代码后,会发现报错:

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

原因

  • 因为Arrays.asList()方法返回的List对象,是一个固定大小的List,不能进行结构上的修改,否则会抛出异常。

  • Arrays.asList()方法得到的List对象并不是java.util.ArrayList对象,而是Arrays内部的ArrayList对象(java.util.Arrays.ArrayList)。源码如下:

    1
    2
    3
    public static <T> List<T> asList(T... a) {
    return new ArrayList<>(a);
    }
  • Arrays.ArrayList类继承自AbstractList,实现了List接口。它重写了add()remove()等修改List结构的方法,并且直接抛出UnsupportedOperationException异常,从而禁止了对List结构的修改。是final类型的a变量。

ArrayList构造源码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
private static class ArrayList<E> extends AbstractList<E>
implements RandomAccess, java.io.Serializable{
private final E[] a;

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

@Override
public int size() {
return a.length;
}
}

AbstractList重写修改List结构的方法源码:

1
2
3
4
5
6
7
8
9
10
11
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E>{
public void add(int index, E element) {
throw new UnsupportedOperationException();
}
public E remove(int index) {
throw new UnsupportedOperationException();
}
public E set(int index, E element) {
throw new UnsupportedOperationException();
}
}

解决办法

总体来说,就是用另外一个新的List来进行操作。只是怎么获取这个新的List的方式不同而已。

构造函数

使用我们熟悉的java.util.ArrayList的构造函数:

1
2
3
4
5
public static void main(String[] args) {
List<String> list = Arrays.asList("a", "b", "c");
List<String> newList = new ArrayList<>(list);
newList.add("d");
}

本文作者: 墨水记忆
本文链接: https://tothefor.com/DragonOne/a2592cba.html
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!