ArrayList<?> alist = new ArrayList<>();
ArrayList<?> blist = new ArrayList<>();
alist.addAll(blist); // 編譯錯誤
alist = blist; // 賦值卻合法
The method addAll(Collection<? extends capture#1-of ?>) in the type ArrayList<capture#1-of ?> is not applicable for the arguments (ArrayList<capture#2-of ?>)
ArrayList<?> 中的 ? 代表未知類型,每次聲明都會生成獨立的捕獲類型(capture#1、capture#2)。addAll 要求參數類型為 Collection<? extends E>,其中 E 是列表的元素類型。由於兩個列表的捕獲類型不同,編譯器無法確認類型兼容,拒絕編譯。alist = blist 只是引用賦值,類型均為 ArrayList<?>,編譯器允許。ArrayList<String> alist = new ArrayList<>();
ArrayList<String> blist = new ArrayList<>();
alist.addAll(blist); // 合法
ArrayList<? extends Object> alist = new ArrayList<>();
ArrayList<? extends Object> blist = new ArrayList<>();
// 仍無法 addAll,因捕獲類型仍不同
// 必須轉型或用輔助方法
public static <T> void safeAddAll(List<T> dest, List<? extends T> src) {
dest.addAll(src);
}
// 調用
safeAddAll(alist, blist); // 編譯器推導 T 為 Object
避免在集合聲明中使用無界通配符 List<?> 作為可變容器。僅在只讀參數(如 void print(List<?> list))中使用。寫入操作請明確泛型參數。