4
我有這樣的代碼時,如Java 7(Eclipse的編譯器)編譯它編譯罰款,但是當我設置的項目設置爲Java 8失敗:通配符泛型在Java 7中的表現不同,8
package scratch;
class Param<T extends Comparable<T>> {
public Comparable<?> get() {
return null;
}
}
public class Condition<T extends Comparable<T>> {
public static <T extends Comparable<T>> Condition<T> isInRange(T lower, T upper) {
return null;
}
public void foo() {
Comparable bound = null; // Line 15
Param<?> param = new Param<Double>();
Condition.isInRange(param.get(), bound); // Line 17
}
}
在Java 7,我收到以下警告:
- 第15行:Comparable是原始類型。引用泛型類型可比應該是參數
- 17行:類型安全:類型條件的一般方法isInRange(T,T)的未選中調用isInRange(可比,可比)
當我行添加<?>
15,報警消失了,後來我在第17行出現錯誤:
綁定不匹配: 類型條件的一般方法isInRange(T,T)是不適用的參數 (可比,可比)。推斷 類型可比不是一個有效的替代品 界參數>
有誰知道究竟是什麼原因導致這種incompability?
PS:我添加了這些醜陋蒙上使代碼的Java的兩個版本下進行編譯:
Condition.isInRange((Comparable)param.get(), (Comparable) bound);
eclipse編譯器在泛型方面有一些缺陷,所以你應該用'javac'進行測試。 – Kayaman
這與通配符無關,但與「綁定」變量的* raw類型*無關。在Java-7中,這有效地關閉了所有關於「isInRange」方法調用的檢查。在Java-8中,目標類型仍然檢測到嵌套調用的無效,類似於[此場景](http://stackoverflow.com/a/26285613/2711488)。我不明白,爲什麼你認爲你的類型轉換爲原始的「比較器」比原始類型的初始使用更醜陋。當然,第二種類型轉換是無意義的,因爲「綁定」已經是一個原始的「可比較」了。 – Holger
@Kayaman:在這種情況下,Eclipse完全符合'javac'。 – Holger