將數組轉爲List的方法,轉換後不可執行List的哪些操作?

方法一

String[] arr={"a","b","c","d"};
List<String> list=new ArrayList<>();
Collections.addAll(list, arr);

方法二

String[] arr={"a","b","c","d"};
List<String> list=new ArrayList<>(arr.length);
for(int i=0;i<arr.length;i++){
    list.add(arr[i]);
}

方法三

String[] arr={"a","b","c","d"};
List<String> list=Arrays.asList(arr);

第三種方法執行add(E e),add(int index,E e),remove(int index),clear()等方法會報UnsupportedOperationException異常。
原因如下:

問題分析

查看asList(T… a)方法源碼可知:

 public static <T> List<T> asList(T... a) {
      return new ArrayList<>(a);
 }

看起來並沒有什麼問題,直接返回一個傳一個參的ArrayList()實例,但是,看API可知,ArrayList中有個構造ArrayList(int initialCapacity),作用是:構造一個具有指定初始容量的空列表。顯然,在這裏傳入的是一個數組。因此,此ArrayList並非彼ArrayList。繼續查看這個ArrayList源碼:

public class Arrays {
    ...
    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);
        }
        ...
    }
}

這個ArrayList是Arrays的私有靜態內部類,同樣繼承了AbstractList抽象方法。看這個ArrayList的構造可知,這裏僅僅是判斷了一下數組是否爲空引用,就直接返回給E[] a數組了,存儲結構並沒有發生變化,還是一個數組類型。看源碼發現並沒有add,clear等方法,那麼看繼承的抽象類AbstractList源碼:

public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {
...
    public boolean add(E e) {
        add(size(), e);
        return true;
    }
    public E set(int index, E element) {
        throw new UnsupportedOperationException();
    }

    public void add(int index, E element) {
        throw new UnsupportedOperationException();
    }

    public E remove(int index) {
        throw new UnsupportedOperationException();
    }

    public void clear() {
        removeRange(0, size());
    }
...
}

這個ArrayList並沒有對add,remove,clear方法重寫,,但重寫了set方法,,所以會拋出UnsupportedOperationException異常。
clear在抽象類中沒有製造異常,也沒有重寫,爲什麼也會拋出異常,暫不清楚。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章