观点:
Arrays.asList()返回的list不能用add方法。
测试:
测试代码:
public static void main(String[] args) {List<String> list = Arrays.asList("Larry", "Moe", "Curly");list.add("test");
}
运行结果:抛出UnsupportedOperationException
异常,这一异常意味着,向list中添加元素是不被允许的。
Exception in thread "main" java.lang.UnsupportedOperationExceptionat java.util.AbstractList.add(AbstractList.java:148)at java.util.AbstractList.add(AbstractList.java:108)at com.fanggeek.test.ArraysTest.main(ArraysTest.java:17)Process finished with exit code 1
理由:
由Arrays的源码可知,Arrays.asList()返回的是Arraylist,不是java.utils.ArrayList,而是一个继承AbstractList的内部类ArrayList,且该内部类并没有重写AbstractList中的add、remove方法。因此asList返回的对象在调用add方法时,实际调用的是AbstractList中的add方法。且由AbstractList的源码可知,直接调用add方法会抛UnsupportedOperationException
异常。因此ArrayList.asList()返回的对象不能用add方法,会抛UnsupportedOperationException
异常。
Arrays.java部分源码:
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);}}@SafeVarargs@SuppressWarnings("varargs")public static <T> List<T> asList(T... a) {return new ArrayList<>(a);}
AbstractList.java部分源码:
public boolean add(E e) {add(size(), e);return true;}public void add(int index, E element) {throw new UnsupportedOperationException();}
解决方案:创建一个真正的ArrayList
由上面可以知道asList()返回的ArrayList不能修改大小,因为这个ArrayList并不是“货真价实”的ArrayList,那么我们可以自行创建一个真正的ArrayList:
代码如下:
public static void main(String[] args) {List<String> list = new ArrayList<>(Arrays.asList("Larry", "Moe", "Curly"));System.out.println("before:" + list);list.add("test");System.out.println("after:" + list);}
在上面的这段代码中,new了一个java.util.ArrayList
,然后再把asList方法的返回值作为构造器的参数传入,最后得到的myList自然是可以自动扩容的。运行结果如下:
before:[Larry, Moe, Curly]
after:[Larry, Moe, Curly, test]Process finished with exit code 0