發現問題
前幾天在看別人的專案的時候,發現一個問題,簡單復現一下這個問題
// 注意這是一個Integer物件的陣列哦
Integer[] arr = new Integer[]{9999,88,77};
List<Integer> list = Arrays.asList(arr);
// 執行以下操作,有問題么?
list.add(1);
list.remove(0);
好的,如果你覺得沒錯,和我剛開始的想法一致,在我沒有認真學習這個asList方法時,天真的以為沒有問題,顧名思義啊,就是把陣列轉換成List唄,
// 恭喜,喜提報錯,如果是這樣測驗該找你麻煩了,/(ㄒoㄒ)/~~
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.AbstractList.add(AbstractList.java:148)
at java.util.AbstractList.add(AbstractList.java:108)
at TestForAsList.main(TestForAsList.java:13)
廢話不多說,我們直接進原始碼里面看看,
@SafeVarargs
@SuppressWarnings("varargs")
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a); // 看起來沒有任何例外,emm,然而呢,這個ArrayList并不是Java.util包下的ArrayList,而是一個在Arrays下實作的內部類,
}

我們發現這個靜態內部類里面并沒有實作List的add和remove方法,那么子類將延用父類AbstractList的方法實作,這個繼承應沒有什么問題,
// 我們進入這個父類的實作,發現了報錯的根源,,
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {
public void add(int index, E element) {
throw new UnsupportedOperationException();
}
public E remove(int index) {
throw new UnsupportedOperationException();
}
}
總結:
究其原因,就是這個asList方法回傳的是一個內部類,只實作了一些遍歷以及更新的方法,下次使用它的時候需要注意一下,
擴展知識點
陣列值的變化
然后我就發現了這個很有意思的點,就是這個Arrays包下的ArrayList用的是構造器傳進來的陣列,并不像我們原來認為的ArrayList的那樣會拷貝陣列然后創建一個新的陣列,
這意味著我們在對這個List進行set的改動時,我們同時會更改原陣列的值,
public static void main(String[] args) {
Integer[] arr = new Integer[]{9999,88,77};
List<Integer> list = Arrays.asList(arr);
list.set(1,0);
System.out.println(list.get(1)); // 輸出0
System.out.println(arr[1]); // 同樣也輸出了0
}
int[]陣列
我們都知道int是基本資料型別,如果我們向asList()方法里面傳入一個int[]陣列會發生什么呢?
我們知道泛型的話需要的是物件型別,基礎資料型別是不能作為泛型的,
// 此時int[]會作為一個物件型別,然后轉換為list,此時長度為1,且可以正常的取出來作為list元素
public static void main(String[] args) {
int[] arr = new int[]{9999,88,77};
List<int[]> list = Arrays.asList(arr);
System.out.println(list.size());
System.out.println(list.get(0)[0]);
System.out.println(list.get(0)[1]);
System.out.println(list.get(0)[2]);
}
好了,asList()方法就學廢了,一天學廢一個小知識/dog
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/504315.html
標籤:其他
上一篇:我無法解決jsdiv隱藏問題
