假設我們有以下的通用類:未指定類型參數
public class GenericClass<U> {
private U value;
public GenericClass(U value) {
this.value = value;
}
}
,並在其他一些MyClass類以下通用方法:
public <T extends BT, BT> void genericMethod(T arg) {
Object genericClass = new GenericClass<BT>(arg);
}
哪個值BT類型參數獲得如果我們打電話
genericMethod("text");
?
一些注意事項:
上面的代碼編譯沒有錯誤或警告,這對我來說似乎很奇怪。 反編譯(由IntelliJ IDEA的2016的裝置)示出了下面的代碼:
public <T extends BT, BT> void genericMethod(T arg) {
new MyClass.GenericClass(arg);
}
注意,新GenericClass<BT>(arg)
是不一樣的new GenericClass(arg)
因爲後者是等效new GenericClass<T>(arg)
(型扣)的,並且儘管T extends BT
,這些都是不同類型和GenericClass
可能具有內部邏輯,其中確切類型名稱發揮重要作用(例如,在某些地圖等中用作字符串鍵)。所以對我來說,很奇怪爲什麼編譯器默默地使用類型推導而不是產生一些警告(或者甚至錯誤),指出BT類型參數沒有被指定。也許我錯過了水手。關於Java泛型重要的,但是......
謝謝你的回答。 什麼是「推理變量」?你可以在我的代碼示例中指向這樣的嗎?在genericMethod()聲明中,我只看到兩個*類型變量*(T和BT)和一個常用變量(arg)。 我在第18.1.1節中讀到了以下內容:_「推理變量是類型的元變量 - 也就是說,它們是允許抽象推理類型的特殊名稱,爲了將它們與類型變量區分開來,推理變量被表示與希臘字母,主要是α「_。然而,它並沒有爲我清楚這個詞。 –
**你寫:** _string延伸BT 這種關係允許編譯器BT綁定到字符串,所以你結束了以下隱含調用: genericMethod( 「文本」)_ - 我不明白爲什麼它允許這樣做:「字符串擴展BT」與「BT ==字符串」不一樣! **您也可以編寫:** _如果不添加更多約束,編譯器會將T等同於BT,並允許您僅調用定義爲BT類型一部分的方法._ - 同樣在這裏!編譯器會更好地產生BT在任何地方都不使用的錯誤。 –
**您寫:** _目前的GenericClass並不是非常有用[...]。你可以認爲U在這方面與Object._ 相同 - 我同意:這個樣本是一個太蒸餾的樣本。在我的真實項目中,_JAXBElement_站在這裏(代替GenericClass)。 –