Java通常可以基於參數(甚至在返回類型上,與例如C#相比)推斷泛型。返回類型推斷的通配符泛型
個例子:我有一個泛型類Pair<T1, T2>
這只是存儲的一對值,可以通過以下方式使用:
Pair<String, String> pair = Pair.of("Hello", "World");
的方法of
看起來就像這樣:
public static <T1, T2> Pair<T1, T2> of(T1 first, T2 second) {
return new Pair<T1, T2>(first, second);
}
非常好。但是,這已不再適用於以下用例,這需要通配符:(注意顯式類型轉換,使List.class
正確的類型)
Pair<Class<?>, String> pair = Pair.of((Class<?>) List.class, "hello");
代碼失敗,出現以下錯誤(提供通過Eclipse中):
類型不匹配:不能從
TestClass.Pair<Class<capture#1-of ?>,String>
轉換爲TestClass.Pair<Class<?>,String>
然而,顯式調用構造函數仍然按預期工作:
Pair<Class<?>, String> pair =
new Pair<Class<?>, String>((Class<?>) List.class, "hello");
有人能解釋這種現象?它是否由設計?是想要?我做錯了什麼,或者我偶然發現了編譯器中的設計/錯誤?
胡亂猜測:「捕獲#1-的?」不知何故似乎暗示通配符由上飛編譯器填充,使得類型Class<List>
,因而失敗的轉換(從Pair<Class<?>, String>
至Pair<Class<List>, String>
) 。這是正確的嗎?有沒有辦法解決這個問題?
爲了完整起見,這裏是Pair
類的簡化版本:
public final class Pair<T1, T2> {
public final T1 first;
public final T2 second;
public Pair(T1 first, T2 second) {
this.first = first;
this.second = second;
}
public static <T1, T2> Pair<T1, T2> of(T1 first, T2 second) {
return new Pair<T1, T2>(first, second);
}
}
看起來轉換器看到「of」的簽名,因爲它返回一個Pair <?擴展類,?擴展類>類型。 對於最終的類,它似乎足夠聰明,減少了擴展部分,這就是爲什麼它不會在字符串上投訴。 –
Zed
2009-08-18 15:08:43
嗯,有趣。感謝您在此鏈接我。 – jjnguy 2011-06-13 19:14:30
它現在在java8中工作。目標類型也被諮詢爲inferene。 – ZhongYu 2015-08-06 17:25:21