調用帶有List<String>
作爲參數就像調用下面的方法,你的方法:
public static List<? super String> m(List<String> list) { ... }
考慮以下起始代碼:
List<String> list = new ArrayList<>();
List<? super String> result = m(list);
這需要上面提到的方法和存儲返回值轉換爲變量result
- 與方法的返回類型完全一致。
現在的問題是:什麼變量 - 或更好的什麼類型 - 你可以分配這個變量?所以我們談論的是分配兼容性。
考慮這些任務:
List<String> result1 = result; // compiler error: type mismatch (not assignable)
List<Object> result2 = result; // compiler error: type mismatch (not assignable)
List result3 = result; // ok
List<?> result4 = result; // ok
List<? super String> result5 = result; // ok
List<? extends Object> result6 = result; // ok
要理解這個錯誤的性質,你必須知道,泛型是不變。這意味着,類型List<String>
不是List<Object>
的子類型 - 儘管類型String
和Object
具有這樣的子類型層次結構。
所以,我們試圖在這裏的是:
- 分配
List<? super String>
到List<String>
=>失敗,無分型
- 分配
List<? super String>
到List<Object>
=>失敗,無分型
- 分配一個
List<? super String>
到List
=>成功,因爲使用原始類型通常從類型檢查中選擇出來
- 將
List<? super String>
指定爲List<?>
=>成功,因爲List<?>
是所有List<...>
- 的超分配
List<? super String>
到List<? super String>
=>成功,因爲...好...
- 分配
List<? super String>
到List<? ectends Object>
=>成功,因爲List<? ectends Object>
是基本上與List<?>
相同。
注意,即試圖分配List<? super String>
到List<? super CharSequence>
或List<? extends CharSequence>
也將失敗。它們不在子類型層次結構中。
這是爲什麼?編譯器不能保證實際列表實例化的類型與約束條件? super/extends CharSequence
相匹配。
例如,我問爲什麼我的'結果'不能成爲'List
爲什麼你使用通配符作爲返回類型?這是一個相當奇怪的事情... – fge
@fge那是庫方法,不是我的。 – bladekp