使用Java中的Arrays.asList()报Exception in thread "main" java.lang.UnsupportedOperationException异常问题
使用Java中的Arrays工具类中的静态方法.asList(...)进行后续操作可能会出现 java.lang.UnsupportedOperationException异常问题
1、问题出现
比如以下例子:
public static void main(String[] args) {
String[] str = {"1","2","3","4"};
List<String> list = Arrays.asList(str);
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()){
iterator.next();
iterator.remove();
}
}
上例中通过Arrays.asList(str)获得一个list,然后我们利用一个迭代器对其中的元素进行删除操作,但是改代码会报如下错误:

2、错误分析
为什么会报这个错误呢?
我们来看一下Arrays.asList()的源码就知道了。
@SafeVarargs
@SuppressWarnings("varargs")
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}
可以看出该静态方法实际上帮我们新建了一个ArrayList,并利用数组a初始化。目前来讲也没啥问题,那么我们继续深入......。去看看这ArrayList有什么特殊之处!
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);
}
@Override
public int size() {
return a.length;
}
从上面源码中可以看出,Arrays这个工具类实际上自己实现了一个内部类ArrayList,而不是调用我们熟知的java.util.ArrayList。
虽然自己实现的这个内部类继承和java.util.ArrayList都是继承AbstractList,但是在AbstractList中的remove、add等方法在AbstractList中是默认throw UnsupportedOperationException,这时候就需要继承的子类重写该方法。
public void add(int index, E element) {
throw new UnsupportedOperationException();
}
/**
* {@inheritDoc}
*
* <p>This implementation always throws an
* {@code UnsupportedOperationException}.
*
* @throws UnsupportedOperationException {@inheritDoc}
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public E remove(int index) {
throw new UnsupportedOperationException();
}
java.util.ArrayList重写了这些方法,而Arrays中自己新建的内部类ArrayList没有重写,所以会抛出异常。
3、解决问题
那么针对这种情况如何解决呢?可以参考以下方式:
public class Test {
public static void main(String[] args) {
String[] str = {"1","2","3","4"};
//以下方式解决
List<String> list = new ArrayList<>(Arrays.asList(str));
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()){
iterator.next();
iterator.remove();
}
}
}
可以通过java.util.ArrayList构造方法直接初始化一个list。因为Arrays.asList(str)实际上返回了一个集合类型。我们可以想象成,str数组的每个元素依次弹出到list中,这种形象的比喻。
4、补充
贴一下java.util.ArrayList的其中一个构造函数源码:


浙公网安备 33010602011771号