List 使用 java.lang.UnsupportedOperationException 异常

Apr 25, 2022 阅读(1145)

标签: Java

最近使用 List 时抛 UnsupportedOperationException  异常,大致的代码如下:

public void test(){
    List<String> list = Arrays.asList("JAVA", "MySQL");
    list.add("Spring");

    System.out.println(list);
}

image-20220425163014848

调试后发现 Arrays.asList() 方法返回的是 Arrays 类中私有的 ArrayList 类,而不是我们认为的 java.util.ArrayList

image-20220425163042566

image-20220425163314381

看了一下  Arrays.ArrayList 源码发现没有重写 add() 方法, 因此实际调用的是 AbstractList.add() 方法,因此抛出了我们看到的 UnsupportedOperationException  的异常。 JDK AbstractList 源码如下:

public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {
    /**
     * Sole constructor.  (For invocation by subclass constructors, typically
     * implicit.)
     */
    protected AbstractList() {
    }

    /**
     * Appends the specified element to the end of this list (optional
     * operation).
     *
     * <p>Lists that support this operation may place limitations on what
     * elements may be added to this list.  In particular, some
     * lists will refuse to add null elements, and others will impose
     * restrictions on the type of elements that may be added.  List
     * classes should clearly specify in their documentation any restrictions
     * on what elements may be added.
     *
     * <p>This implementation calls {@code add(size(), e)}.
     *
     * <p>Note that this implementation throws an
     * {@code UnsupportedOperationException} unless
     * {@link #add(int, Object) add(int, E)} is overridden.
     *
     * @param e element to be appended to this list
     * @return {@code true} (as specified by {@link Collection#add})
     * @throws UnsupportedOperationException if the {@code add} operation
     *         is not supported by this list
     * @throws ClassCastException if the class of the specified element
     *         prevents it from being added to this list
     * @throws NullPointerException if the specified element is null and this
     *         list does not permit null elements
     * @throws IllegalArgumentException if some property of this element
     *         prevents it from being added to this list
     */
    public boolean add(E e) {
        add(size(), e);
        return true;
    }


    /**
     * {@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();
    }

知道了原因,修改代码时使用 java.util.ArrayList 即可,代码如下:

class Solution {
    public void test(){
        List<String> list = new ArrayList<>(Arrays.asList("JAVA", "MySQL"));
        list.add("Spring");

        System.out.println(list);
    }
}

 

总结:  Arrays.asList() 方法返回的 ArrayList 是Arrays 类下私有的 ArrayList  类实例(并不是 java.util.ArrayList 类的实例),这个私有的 ArrayList  是一个简陋版的 List 实现(add、 remove、subList 等一下方法都没有实现)。

MongoDB学习园