Arrays.asList 报错 UnsupportedOperationException

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

import java.util.Arrays;
import java.util.List;
/**
 * @author [email protected]
 * @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  List asList(T... a) {
        return new ArrayList<>(a);
    }

    /**
     * @serial include
     */
    private static class ArrayList extends AbstractList
        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));

你可能感兴趣的:(Arrays.asList 报错 UnsupportedOperationException)