Java 异常汇总记录(一)

java.lang.UnsupportedOperationException

错误源头

操作 Collection 方法错误:java.lang.UnsupportedOperationException

这个错误出现在使用 Arrays.asList(T... a) 方法中,这个方法返回一个 ArrayList 对象,并且调用 add、remove、retains...等方法,此时就会抛出这个异常错误。

之所以会出现这个错误,因为 Arrays.asList(T... a)Arrays 的内部实现的类,而不是 java.util.ArrayList 类。

Arrays 内部类 ArrayList 继承 AbstractList 类,这个类是一个抽象类,本身的这些方法是默认抛出异常。

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

Arrays 内部类 ArrayList 并没有重写这几个方法,所以调用的时候是从父类继承来的默认行为。自然而然的就会执行父类的方法,而父类默认抛出异常,很正常的逻辑。

Array.asList(T... a) 方法代码

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

使用 IDEA 紧跟着代码可以找到 Arrays 的内部类。

image.png

解决方法

通过上面的一大堆文字描述,可以清楚的知道运行时为什么会抛出这个异常,而在编译的时候没有报错。

java.util.ArrayList 类的其中有一个构造器可以将实现 Collection 接口的实现类作为参数实例化。

public ArrayList(Collection<? extends E> c) {
    elementData = c.toArray();
    if ((size = elementData.length) != 0) {
        // c.toArray might (incorrectly) not return Object[] (see 6260652)
        if (elementData.getClass() != Object[].class)
            elementData = Arrays.copyOf(elementData, size, Object[].class);
    } else {
        // replace with empty array.
        this.elementData = EMPTY_ELEMENTDATA;
    }
}

Arrays.asList(T... a) 返回的结果作为这个构造器的参数,可以将其转化为 java.util.ArrayList 类的结果。

这样就可以使用这些方法了。