String[] arr = {"a", "b", "c"};
List list = Arrays.asList(arr);
list.add("d"); // 拋出 java.lang.UnsupportedOperationException
list.remove(0); // 拋出 java.lang.UnsupportedOperationException
Arrays.asList() 返回 **`java.util.Arrays$ArrayList`**(內部私有靜態類),**不是** `java.util.ArrayList`。
AbstractList (java.util) ├── ArrayList (java.util) // 重寫了 add/remove/set 等修改方法 └── Arrays$ArrayList (java.util.Arrays) // **未重寫**修改方法,繼承 AbstractList 默認拋異常
AbstractList 默認實現:
public boolean add(E e) { throw new UnsupportedOperationException(); }
public E remove(int index) { throw new UnsupportedOperationException(); }
public E set(int index, E element) { throw new UnsupportedOperationException(); }
private static class ArrayListextends AbstractList implements RandomAccess, java.io.Serializable { final E[] a; ArrayList(E[] array) { a = Objects.requireNonNull(array); } public int size() { return a.length; } public Object[] toArray() { return a.clone(); } public E get(int index) { return a[index]; } public E set(int index, E element) { // 僅實現了 set E old = a[index]; a[index] = element; return old; } // **無 add/remove/clear 等擴容方法** —— 因為底層數組長度固定 }
ListmutableList = new ArrayList<>(Arrays.asList(arr)); // 或 Java 9+ List.of + new ArrayList<> List mutableList = new ArrayList<>(List.of("a", "b", "c"));
Listlist = Arrays.stream(arr).collect(Collectors.toList()); // 或 List list = Stream.of(arr).collect(Collectors.toCollection(ArrayList::new));
list = Arrays.asList(arr); arr[0] = "z"; System.out.println(list.get(0)); // 輸出 "z" —— **共享底層數組引用** list.set(1, "y"); System.out.println(arr[1]); // 輸出 "y" —— 雙向影響
對策:若需完全隔離,**必須拷貝**(方案一/二/三均會拷貝)。
| 方案 | 耗時 (ns/op) | 分配率 | 推薦場景 |
|---|---|---|---|
| new ArrayList<>(Arrays.asList(arr)) | ~120 | 2 個對象 | 通用首選 |
| Collections.addAll(new ArrayList<>(len), arr) | ~100 | 1 個對象 | 高頻熱點路徑 |
| Stream.of(arr).collect(toList()) | ~180 | 3+ 對象 | 函數式管道中 |