java.lang.UnsupportedOperationException是java不支持操作异常
在对Arrays.asList(T... a)生成的List集合进行add或者remove操作的时候出现的异常
出现场景:在使用Arrays.asList(T... a)将一个数组转成list,然后对这个list进行add,remove操作就会出现这个异常,
例如:
String[] codes = "1-2-3-4".split("-");;
List<String> parentCodes = Arrays.asList(codes);
parentCodes.remove(1);
然而用List<T> list = new ArrayList<>()声明的集合,对原生的list操作add,remove方法就不会出现这个异常。
原因就是:你如果够细心,你就会点开Arrays.asList(T... a)查看它的返回值
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}
private static class ArrayList<E> extends AbstractList<E>
implements RandomAccess, java.io.Serializable
{
private static final long serialVersionUID = -2764017481108945198L;
private final E[] a;
ArrayList(E[] array) {
a = Objects.requireNonNull(array);
}
.
.
.
}
这个list并不是List<T> list = new ArrayList<>()而是Arrays的内部ArrayList,
List<T> list = new ArrayList<>()的ArrayList是这样定义的:
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
private static final long serialVersionUID = 8683452581122892189L;
}
你会发现上面Arrays里面的ArrayList是Arrays类的内部类,跟ArrayList类一样都继承了AbstractList,remove,add等方法。
再来看一下 在AbstractList<E>类中的remove方法
public E remove(int index) {
throw new UnsupportedOperationException();
}
什么处理都没有做,直接抛出UnsupportedOperationException()异常,
所以说到这里你应该知道原因了:那就是通过源码你会发现 Arrays内部ArrayList并没有重写AbstractList类的remove方法,所以就会直接抛出异常。
再看看ArrayList类的源码:
public E remove(int index) {
rangeCheck(index);
modCount++;
E oldValue = elementData(index);
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work
return oldValue;
}
可见是对remove方法进行了重写的,所以遇到这个异常就不要慌,知道为什么会出现这个异常,你就知道怎么解决了。
String[] codes = "1-2-3-4".split("-");
List<String> parentCodes = new ArrayList<>(Arrays.asList(codes));
parentCodes.remove(codes.length-1);
那就是把用Arrays.asList()生成的集合再生成new ArrayList<>(),这样就ok了。