您提出的簽名可能適用於Java-8。然而在以前的Java版本中,類型推斷並不那麼聰明。考慮你有List<java.sql.Date>
。請注意,java.sql.Date
延伸java.util.Date
其實施Comparable<java.util.Date>
。當你編譯時
List<java.sql.Date> list = new ArrayList<>();
Collections.sort(list);
它在Java-7中完美的工作。這裏推薦T
爲java.sql.Date
,實際上是Comparable<java.util.Date>
,即Comparable<? super java.sql.Date>
。但是讓我們試試你的簽名:
public static <T extends Comparable<T>> void sort(List<? extends T> list) {}
List<java.sql.Date> list = new ArrayList<>();
sort(list);
這裏T
應該被推斷爲java.util.Date
。但是Java 7規範不允許這樣的推斷。因此,該代碼可與Java-8進行編譯,但失敗時的Java-7下彙編:
Main.java:14: error: method sort in class Main cannot be applied to given types;
sort(list);
^
required: List<? extends T>
found: List<Date>
reason: inferred type does not conform to declared bound(s)
inferred: Date
bound(s): Comparable<Date>
where T is a type-variable:
T extends Comparable<T> declared in method <T>sort(List<? extends T>)
1 error
類型推斷用Java-8大大提高。單獨的JLS chapter 18現在專用於此,而在Java-7中,規則were要簡單得多。
但是,static> T max(Collection extends T> c)工作正常......這又是一個推理問題嗎? –
prvn
@prvn,在這裏你有'Comparable super T>'而不是'Comparable'就像你的簽名中一樣。 ''T擴展Comparable super T>>無效排序(列表 extends T>列表)'也會工作,但添加'?擴展T'在這裏完全沒有必要,而在'max'方法中合理(如'max'返回值)。 –
還有一點。當你有一個像'List extends T> list'這樣的通配符類型時,由於通配符類型的工作方式,你不能在該方法內執行'list.set(index,list.get(anotherIndex))'。這可以通過內部幫助方法來避開'?將T'擴展到另一個類型變量(或者通過使用未經檢查的操作,正如內部實現經常這樣做),但是仍然沒有通配符的類型對於將要修改的列表來說更清晰。 – Holger