簡體   English   中英

泛型方法類型參數推斷問題

[英]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[] (因為IntegerNumber的子類)
  • 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM