Arrays.asList 报错 UnsupportedOperationException

一个数组转成list,调用removeadd方法报 UnsupportedOperationException,样例如下:

import java.util.Arrays;
import java.util.List;
/**
 * @author lfg1991@qq.com
 * @create 2017-04-27 13:53
 **/
public class ArraysDemo {
    public static void main(String[] args) {
        String[] str = {"5", "7", "8"};

        List list = Arrays.asList(str);
        list.remove(0); //UnsupportedOperationException

        System.out.println(list);
        System.out.println(Arrays.toString(str));
    }
}

Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.AbstractList.remove(AbstractList.java:161)
at me.douwo.ArraysDemo.main(ArraysDemo.java:18)

原因: Arrays内部有个静态ArrayList类继承了AbstractList,但是并没有重写 add、remove 方法,Arrays.asList采用内部ArrayList类new的对象,add、remove调用的是父类AbstractList中的方法,父类并没有真正的实现。

Arrays.asList 源码

   @SafeVarargs
    public static <T> List<T> asList(T... a) {
        return new ArrayList<>(a);
    }

    /**
     * @serial include
     */
    private static class ArrayList<E> extends AbstractList<E>
        implements RandomAccess, java.io.Serializable
    {
        private static final long serialVersionUID = -2764017481108945198L;
        private final E[] a;
        ...

java.util.AbstractList 源码

    public void add(int index, E element) {
        throw new UnsupportedOperationException();
    }
    public E remove(int index) {
        throw new UnsupportedOperationException();
    }

Arrays.asList 返回的是一个list,但是内部实际上是一个定长数组,不能增、删,可以修改,修改会改变原始数组,原始数组和内部数组是同一个。见源码:

        private final E[] a;
        ArrayList(E[] array) {
            if (array==null)
                throw new NullPointerException();
            a = array;
        }

所以Arrays.asList 最好作为只读的list使用,解决方法就是使用 正经的ArrayList

    List list = new ArrayList(Arrays.asList(str));
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容