写代码时遇到下面情况:
List<String> list = Arrays.asList("1,2,3,4".split(","));
list.add("5"); // 报错java.lang.UnsupportedOperationException
查看Arrays.asList代码
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}
按理返回一个ArrayList,不会add报错,其实不然
跟踪这个ArrayList,实际是定义在Arrays内部
private static class ArrayList<E> extends AbstractList<E>
implements RandomAccess, java.io.Serializable
{
private final E[] a;
ArrayList(E[] array) {
a = Objects.requireNonNull(array);
}
}
这是一个静态内部类,跟java.util.ArrayList不是一回事。
那么为什么要重写一个ArrayList?
从实现AbstractList来看,这个类实现了一下几类方法:
- size、get、indexOf、contains、forEach等读方法
- toArray、set、replaceAll、sort等修改方法
这些方法都不会造成元素数量的变化。
没有实现的方法是add、remove等会使元素数量改变的方法,如果调用list.add,会调用AbstractList#add,而AbstractList的实现:
public void add(int index, E element) {
throw new UnsupportedOperationException();
}
所以抛出如上异常。
再看Arrays.asList的注释:
Returns a fixed-size list backed by the specified array.
说明,返回的是一个元素数量固定大小的list。