ArrayList报错:UnsupportedOperationException的解决办法
在软件构造Lab2实验时遇到一个问题:使用list.add()函数报出如下错误:
首先查看简化后的报错部分的代码:
逐级查看源码,首先查看Arrays.asList()函数:
/**
* Returns a fixed-size list backed by the specified array. (Changes to
* the returned list "write through" to the array.) This method acts
* as bridge between array-based and collection-based APIs, in
* combination with {@link Collection#toArray}. The returned list is
* serializable and implements {@link RandomAccess}.
*
* <p>This method also provides a convenient way to create a fixed-size
* list initialized to contain several elements:
* <pre>
* List<String> stooges = Arrays.asList("Larry", "Moe", "Curly");
* </pre>
*
* @param <T> the class of the objects in the array
* @param a the array by which the list will be backed
* @return a list view of the specified array
*/
@SafeVarargs
@SuppressWarnings("varargs")
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}
可以看出返回的是Arrays私有的ArrayList类的列表,继承了AbstractList,据此继续查找,可以查找到此ArrayList定义的部分:
private static class ArrayList<E> extends AbstractList<E>
代码查找发现该类未重写add()方法,于是查看AbstractList中关于add()方法的定义:
public boolean add(E e) {
add(size(), e);
return true;
}
继续查找,发现abstractList对add()方法的定义为:
/**
* {@inheritDoc}
*
* <p>This implementation always throws an
* {@code UnsupportedOperationException}.
*
* @throws UnsupportedOperationException {@inheritDoc}
* @throws ClassCastException {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
* @throws IllegalArgumentException {@inheritDoc}
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public void add(int index, E element) {
throw new UnsupportedOperationException();
}
可以看出,Arrays.asList()返回的私有的ArrayList实际上并未实现add()方法,也就是其抛出UnsupportedOperationException的真正原因,但是定义部分的List是使用泛型接口定义的类,然而AbstractList的定义如下:
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E>
AbstractList实现了List,因此在会逃过静态代码审查的检测,我们正常情况下使用的ArrayList是java.util.ArrarList。实现了add()方法,因此可正常使用。