最近使用 List 时抛 UnsupportedOperationException 异常,大致的代码如下:
public void test(){ List<String> list = Arrays.asList("JAVA", "MySQL"); list.add("Spring"); System.out.println(list); }
调试后发现 Arrays.asList() 方法返回的是 Arrays 类中私有的 ArrayList 类,而不是我们认为的 java.util.ArrayList。
看了一下 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 等一下方法都没有实现)。