關於Arrays.asList返回List無法新增和刪除?

柳~發表於2024-08-22

關於Arrays.asList返回的List無法新增和刪除?

這個是在寫專案的時候發現的,然後就分析了一下原始碼,得其內部原理

復現程式碼示例:

public class ArraysAsList {
    public static void main(String[] args) {
        Integer[] array = {1, 2, 3, 4, 5};
        List<Integer> list = Arrays.asList(array);
        list.forEach(System.out::println);
        list.add(11);
    }
}

程式執行至list.add(11)時報錯

Exception in thread "main" java.lang.UnsupportedOperationException

分析原始碼:

點選檢視Arrays.asList原始碼,靜態的返回 List 的方法

image-20240822092303194

看一下asList裡面 new ArrayList的程式碼實現,就會發現這裡的ArrayList並不是java.util.ArrayList中的單列集合,而是Arrays工具類(java.util.Arrays)中的靜態內部類ArrayList

image-20240822090509143

image-20240822091109703

然後迴歸到Arrays.asList()方法,為什麼這個方法生成的List集合無法在add和remove

因為這裡返回的是一個 final 陣列,陣列本身就是不可變的,所以當呼叫Arrays.asList方法返回一個集合後,無法在對這個集合進行一些操作,這個是陣列的特性

private final E[] a;

ArrayList(E[] array) {
    a = Objects.requireNonNull(array);
}

至於為什麼java.util包下的ArrayList的底層也是陣列,但是它依然可以去add和remove,那是因為copy了,但是在Arrays下面的ArrayList靜態內部類中,它並沒有實現add和remove方法用來對集合進行新增和刪除,看下圖:

image-20240822091617505

也就是說我們可以呼叫get方法得到Arrays.asList返回的集合元素,也可以set修改這裡面的值,但是因為它沒有add和remove方法所以無法對集合進行增加和刪除,這也是為什麼會報錯:UnsupportedOperationException(沒有支援的方法)的原因。

至此我認為Arrays.asList的問題就講完了,但是在寫這個示例的時候我發現了一個新的知識函式式介面,之前瞭解過,但是不是很熟悉。

如果你是為了明白Arrays.asList的問題,那麼到這裡就可以止步了。

相關文章