观点:
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.UnsupportedOperationException
at 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