####關於Arrays.asList(T)這個APIhtml
參考: https://docs.oracle.com/javase/tutorial/java/generics/why.html https://docs.oracle.com/javase/tutorial/java/data/autoboxing.htmljava
因此會研究這個問題,是由於在寫代碼的時候遇到了這個,很反直覺. 一樣都是{120,130}居然返回了不一樣的類型.數組
public static void main(String[] args) { Integer[] pangs = {120, 130}; int[] fats = {120, 130}; List<Integer> pangList = Arrays.asList(pangs); List<int[]> fatsList = Arrays.asList(fats); }
Auto boxing is the automatic conversion that the Java compiler makes, between the
primitive types
and theircorresponding object wrapper classes
.oracle
Generic Types A generic type is a generic
class
orinterface
that is parameterized over types.app
如下是對返回類型推斷的一些解釋(軍功章的一半分給石五花
), 首先明確兩點dom
而後看傳入Arrays.asList(fats)的fats的類型是int[]
注意int[]並非基本數據類型, 基本數據類型是一回事而,基本數據類型的數組又是另一回事.
因此這裏並無想固然的auto boxing發生.ide
接着就是vargs, ...一般在編譯時會轉變成對應的一維數組 對應這裏的上下文即int[]
[] 數據類型爲int[]
的一維數組 因此返回的類型就是List<int[]>
設計
編譯時類型是List,可是運行時的類型是java.util.Arrays.ArrayList.code
String[] str = {"hello","world"} List<String> listStr = Arrays.asList(str); //這裏就要拋異常了 listStr.add("shit")
* Returns a fixed-size list backed by the specified array. (Changes to * the returned list "write through" to the array.) This method acts * as bridge between array-based and collection-based APIs, in * combination with {@link Collection#toArray}. The returned list is * serializable and implements {@link RandomAccess}. * @param <T> the class of the objects in the array * @param a the array by which the list will be backed * @return a list view of the specified array */ @SafeVarargs @SuppressWarnings("varargs") public static <T> List<T> asList(T... a) { return new ArrayList<>(a); }
重點就是這兩句: Returns a fixed-size list backed by the specified array.
return a list view of the specified array.
htm
This method acts as bridge between array-based and collection-based APIs. 把原先基於數組的改爲基於collection的,方便你可能會調用一些collection相關的API.
public static <T> List<T> asList(T... a) { return new ArrayList<>(a); }
這個代碼命名很雞賊,就叫的ArrayList
. 注意這裏的ArrayList可不是那個經常使用的--->java.util.ArrayList. 它是---->java.util.Arrays.ArrayList. 而後看它代碼的實現.聲明長這個樣子
private static class ArrayList<E> extends AbstractList<E> implements RandomAccess, java.io.Serializable{ ... }
java.util.AbstractList這個類的聲明
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {}
public abstract class AbstractCollection<E> implements Collection<E>
這是java.util.List這個類的聲明
public interface List<E> extends Collection<E> { ... }
這就是爲啥你在外面能夠用List來接,你懂我意思.
Exception in thread "main" java.lang.UnsupportedOperationException 至於那個異常,是java.util.AbstractList拋出的,它壓根就沒有實現. 你的java.util.ArrayList能夠這麼幹是由於它本身實現了.
這是AbstractList類的add方法
public void add(int index, E element) { throw new UnsupportedOperationException(); }
####問題來了,爲何Java要把它設計成fixed-size的呢?
僅僅
是acts as bridge between array-based and collection-based APIs嗯 數組原本就是fixed-size的.
事實上java.util.Arrays.ArrayList裏是提供了相應的API好比set,get什麼的.public E get(int index) { return a[index]; } @Override public E set(int index, E element) { E oldValue = a[index]; a[index] = element; return oldValue; }
只要不動大小怎麼着均可以. 若是你改變數組的大小了,就不是原來那個數組了.
但是若是就是想要一個不fixed-size的List的話,能夠這麼着
int[] fats = {120,130}; new ArrayList(Arrays.asList(fats));
這把返回的就是經常使用的java.util.ArrayList了.