java.util.Arrays$ArrayList
(下文:Arrays$ArrayList
)是java.util.Arrays
的私有靜態內部類,他實現的接口,繼承的父類幾乎和java.util.ArrayList
(下文:ArrayList
)相同,既然是私有的,那麼日常應該是咱們少關注的地方。本文嘗試對比一兩個他們之間的不一樣點。java
構造擁有三個字符串的List
,ArrayList
數組
List<String> lb = new ArrayList<>(3); lb.add("a"); lb.add("b"); lb.add("c");
Arrays$ArrayList
ide
List<String> la = Arrays.asList("a", "b", "c"); //源碼 public static <T> List<T> asList(T... a) { return new ArrayList<>(a); }
二者都知足了需求,後者看起來比前者簡潔,除此以外二者還有什麼不一樣呢。this
支持的操做,spa
lb.add("d") lb.remove("d")
不支持的操做,這將會拋出異常java.lang.UnsupportedOperationException
code
la.add("d") la.remove("d")
可見Arrays$ArrayList
不容許增長也不容許刪除。blog
在Arrays$ArrayList
類,
首先並無override父類的add
方法,因此這個方法來自他的父類AbstractList
;
看AbstractList
中的add
方法繼承
public boolean add(E e) { add(size(), e); return true; } public void add(int index, E element) { throw new UnsupportedOperationException(); }
最終調用的方法拋出了異常UnsupportedOperationException
。
相比較ArrayList
接口
public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true; } public void add(int index, E element) { rangeCheckForAdd(index); ensureCapacityInternal(size + 1); // Increments modCount!! System.arraycopy(elementData, index, elementData, index + 1, size - index); elementData[index] = element; size++; }
這兩個方法都在ArrayList
中實現了,或者擴容而後在尾部插入,或者擴容、移動數組元素,而後插入到指定的下標位置。ip
Arrays$ArrayList
的remove(Object)
方法繼承自AbstractList
的父類AbstractCollection
,其中
public boolean remove(Object o) { Iterator<E> it = iterator(); if (o==null) { while (it.hasNext()) { if (it.next()==null) { it.remove(); return true; } } } else { while (it.hasNext()) { if (o.equals(it.next())) { it.remove(); return true; } } } return false; }
這裏使用了迭代器的方式進行刪除,看這個方法的註釋
若是這個迭代器沒有實現remove
方法的話,那麼這整個方法也將要拋出UnsupportedOperationException
異常的。
在AbstractCollection
中iterator
是一個抽象方法,之於Arrays$ArrayList
,這個方法實現的位置仍是在AbstractList
,
public Iterator<E> iterator() { return new Itr(); } private class Itr implements Iterator<E> { //...省略 public void remove() { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { AbstractList.this.remove(lastRet); if (lastRet < cursor) cursor--; lastRet = -1; expectedModCount = modCount; } catch (IndexOutOfBoundsException e) { throw new ConcurrentModificationException(); } } }
到這裏咱們發現AbstractList
實現了AbstractCollection
的iterator
方法,並且返回的迭代器也實現了remove
方法,不是上文提到的註釋那種狀況。可是爲何刪除動做仍是不容許的呢?
具體這個迭代器的remove
方法,
AbstractList.this.remove(lastRet);
可見迭代器最終也是調用容器類的remove
方法的,那麼Arrays$ArrayList
沒有實現remove
方法,而AbstractList
的remove
方法,以下
public E remove(int index) { throw new UnsupportedOperationException(); }
所以,即便在AbstractList
中使用迭代器進行刪除操做,但因爲Arrays$ArrayList
沒有實現remove
且繼承的remove
拋出UnsupportedOperationException
異常,最終在Arrays$ArrayList
是不容許刪除操做的。
值得注意的是,AbstractList
的迭代器是否要調用remove(int)
方法是由要刪除的目標是否數組的元素決定的,若是不存在這樣的元素,則下面的代碼並不會出現異常,
List<String> la = Arrays.asList("a", "b", "c"); la.remove("e");