List<String> list = Arrays.asList("A", "B", "C");
list.add("D"); // 拋出 UnsupportedOperationException
@SafeVarargs
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a); // 注意:這是 Arrays 內部類,非 java.util.ArrayList
}
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) {
if (array == null) throw new NullPointerException();
a = array;
}
// --- 僅實現只讀操作 ---
public int size() { return a.length; }
public E get(int index) { return a[index]; }
public E set(int index, E element) { // 僅支持替換
E old = a[index];
a[index] = element;
return old;
}
public int indexOf(Object o) { ... }
public boolean contains(Object o) { return indexOf(o) != -1; }
public Object[] toArray() { return a.clone(); }
public <T> T[] toArray(T[] a) { ... }
// --- 未重寫 add/remove/clear 等修改長度的方法 ---
// 繼承自 AbstractList,默認拋出 UnsupportedOperationException
}
public void add(int index, E element) {
throw new UnsupportedOperationException();
}
public E remove(int index) {
throw new UnsupportedOperationException();
}
public boolean addAll(Collection<? extends E> c) {
// 內部調用 add(),同樣拋出異常
}
Serializable、RandomAccess。// 方式 1:構造函數複製(推薦,語義清晰)
List<String> mutable = new ArrayList<>(Arrays.asList("A", "B", "C"));
mutable.add("D"); // OK
// 方式 2:Stream API(JDK 8+)
List<String> mutable = Stream.of("A", "B", "C")
.collect(Collectors.toCollection(ArrayList::new));
// 方式 3:Collections.addAll(舊版本兼容)
List<String> mutable = new ArrayList<>();
Collections.addAll(mutable, "A", "B", "C");
| 誤區代碼 | 後果 | 修正 |
|---|---|---|
Arrays.asList(1,2,3).add(4) | 運行時拋異常 | 外層包裹 new ArrayList<>(...) |
List | 編譯錯誤:基本類型無法泛型化 | 用 Integer 或 IntStream.of(...).boxed().collect(...) |
| 修改返回 List 元素影響原數組 | list.set(0, "X") 會修改原數組 | 若需隔離,先 Arrays.copyOf(arr, arr.length) |
Arrays.asList 返回的是固定大小、底層共享數組、僅支持 set/get/遍歷的 List 視圖。需要增刪操作時,務必拷貝構造新 ArrayList。理解此機制能避免線上「不可修改集合」異常。