[英]Generic Method Type Argument Inference Issue
我無法理解為什么下面的第二次調用會導致編譯器錯誤。 為什么不能像第一次調用那樣將 Number 推斷為類型參數?
typeArgInference(new Integer[100], new ArrayList<Number>()); // Infers Number
typeArgInference(new Number[100], new ArrayList<Integer>()); // compiler error
<T> void typeArgInference(T[] a, Collection<T> c) {}
可能是我在這里遺漏了一些東西。 如果 JLS 對此行為有任何規定,請務必包含鏈接。
泛型是不變的,數組是協變的:
Integer[]
可以作為Number[]
(因為Integer
是Number
的子類)ArrayList<Integer>
不能充當ArrayList<Number>
(因為您可以向后者添加例如Double
,但您不能將Double
添加到Integer
列表中)。 當然,您可以嘗試將Double
放入Number[]
,但如果您的Number[]
確實是一個Integer[]
,則會因ArrayStoreException
而失敗。 這將是運行時故障。
在語言支持泛型之前,讓數組協變對於擁有某種泛型的集合是一種胡說八道。 人們意識到這是一個問題(因為運行時失敗很糟糕),因此為什么泛型被設計為不變的。
由於您要求提供 JLS 鏈接:
如果您向列表類型添加了上限,您的兩個示例都將編譯:
<T> void typeArgInference(T[] a, Collection<? extends T> c) {}
在這兩種情況下, Number
都是滿足類型約束的類型:
Integer[]
可以作為Number[]
; 和ArrayList<Number>
是一個Collection<Number>
,這是一個Collection<? extends Number>
Collection<? extends Number>
。Number[]
可以充當Number[]
(顯然); 和ArrayList<Integer>
是一個Collection<Integer>
,這是一個Collection<? extends Number>
Collection<? extends Number>
。 然后,您無法在該方法中向Collection
添加任何內容(文字null
除外;或者通過原始類型破壞類型安全)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.