java.util.Arrays$ArrayList addAll报错
执行下面代码时报错:
List<String> centerList = WebConstants.SUPPORT_BIG_CENTERS_LIST; // WebConstants.SUPPORT_BIG_CENTERS_LIST 是 Arrays.asList 转化来的
centerList.removeAll(WebConstants.SUPPORT_CENTERS_LIST);
centerList.addAll(WebConstants.SUPPORT_CENTERS_LIST);
最后一行报错:
java.lang.UnsupportedOperationException: null at java.util.AbstractList.add(AbstractList.java:148) ~[na:1.8.0_101] at java.util.AbstractList.add(AbstractList.java:108) ~[na:1.8.0_101] at java.util.AbstractCollection.addAll(AbstractCollection.java:344)~[na:1.8.0_101]
查看 Arrays$ArrayList 的源代码,如下 (1.8 版本):
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 </span>=<span style="color: rgba(0, 0, 0, 1)"> Objects.requireNonNull(array); } @Override </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> size() { </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> a.length; } @Override </span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> Object[] toArray() { </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> a.clone(); } @Override @SuppressWarnings(</span>"unchecked"<span style="color: rgba(0, 0, 0, 1)">) </span><span style="color: rgba(0, 0, 255, 1)">public</span> <T><span style="color: rgba(0, 0, 0, 1)"> T[] toArray(T[] a) { </span><span style="color: rgba(0, 0, 255, 1)">int</span> size =<span style="color: rgba(0, 0, 0, 1)"> size(); </span><span style="color: rgba(0, 0, 255, 1)">if</span> (a.length <<span style="color: rgba(0, 0, 0, 1)"> size) </span><span style="color: rgba(0, 0, 255, 1)">return</span> Arrays.copyOf(<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.a, size, (Class</span><? <span style="color: rgba(0, 0, 255, 1)">extends</span> T[]><span style="color: rgba(0, 0, 0, 1)">) a.getClass()); System.arraycopy(</span><span style="color: rgba(0, 0, 255, 1)">this</span>.a, 0, a, 0<span style="color: rgba(0, 0, 0, 1)">, size); </span><span style="color: rgba(0, 0, 255, 1)">if</span> (a.length ><span style="color: rgba(0, 0, 0, 1)"> size) a[size] </span>= <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">; </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> a; } @Override </span><span style="color: rgba(0, 0, 255, 1)">public</span> E get(<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> index) { </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> a[index]; } @Override </span><span style="color: rgba(0, 0, 255, 1)">public</span> E set(<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> index, E element) { E oldValue </span>=<span style="color: rgba(0, 0, 0, 1)"> a[index]; a[index] </span>=<span style="color: rgba(0, 0, 0, 1)"> element; </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> oldValue; } @Override </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> indexOf(Object o) { E[] a </span>= <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.a; </span><span style="color: rgba(0, 0, 255, 1)">if</span> (o == <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">) { </span><span style="color: rgba(0, 0, 255, 1)">for</span> (<span style="color: rgba(0, 0, 255, 1)">int</span> i = 0; i < a.length; i++<span style="color: rgba(0, 0, 0, 1)">) </span><span style="color: rgba(0, 0, 255, 1)">if</span> (a[i] == <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">) </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> i; } </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> { </span><span style="color: rgba(0, 0, 255, 1)">for</span> (<span style="color: rgba(0, 0, 255, 1)">int</span> i = 0; i < a.length; i++<span style="color: rgba(0, 0, 0, 1)">) </span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (o.equals(a[i])) </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> i; } </span><span style="color: rgba(0, 0, 255, 1)">return</span> -1<span style="color: rgba(0, 0, 0, 1)">; } @Override </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">boolean</span><span style="color: rgba(0, 0, 0, 1)"> contains(Object o) { </span><span style="color: rgba(0, 0, 255, 1)">return</span> indexOf(o) != -1<span style="color: rgba(0, 0, 0, 1)">; } @Override </span><span style="color: rgba(0, 0, 255, 1)">public</span> Spliterator<E><span style="color: rgba(0, 0, 0, 1)"> spliterator() { </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> Spliterators.spliterator(a, Spliterator.ORDERED); } @Override </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span> forEach(Consumer<? <span style="color: rgba(0, 0, 255, 1)">super</span> E><span style="color: rgba(0, 0, 0, 1)"> action) { Objects.requireNonNull(action); </span><span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)"> (E e : a) { action.accept(e); } } @Override </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span> replaceAll(UnaryOperator<E><span style="color: rgba(0, 0, 0, 1)"> operator) { Objects.requireNonNull(operator); E[] a </span>= <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.a; </span><span style="color: rgba(0, 0, 255, 1)">for</span> (<span style="color: rgba(0, 0, 255, 1)">int</span> i = 0; i < a.length; i++<span style="color: rgba(0, 0, 0, 1)">) { a[i] </span>=<span style="color: rgba(0, 0, 0, 1)"> operator.apply(a[i]); } } @Override </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span> sort(Comparator<? <span style="color: rgba(0, 0, 255, 1)">super</span> E><span style="color: rgba(0, 0, 0, 1)"> c) { Arrays.sort(a, c); } }</span></pre>
进入父类找下 addAll 方法:
public boolean addAll(int index, Collection<? extends E> c) {rangeCheckForAdd(index); boolean modified = false; for (E e : c) { add(index++, e); modified = true; } return modified; }
实现只存在于父类中,如下所示:
public void add(int index, E element) { throw new UnsupportedOperationException();}
父类AbstractList add 方法直接抛出异常。
所以问题就在这里,我们改下代码,如下就不报错了:
List<String> centerList = new ArrayList<>();
if (null != WebConstants.SUPPORT_BIG_CENTERS_LIST) { //addAll 的目标是 null 会报错
centerList.addAll(WebConstants.SUPPORT_BIG_CENTERS_LIST);
}
if (null != WebConstants.SUPPORT_CENTERS_LIST) {
centerList.removeAll(WebConstants.SUPPORT_CENTERS_LIST);
centerList.addAll(WebConstants.SUPPORT_CENTERS_LIST);
}
它调用的就是 arrayList 的 addAll 方法了