我偶然發現了JavaFx的這個問題,但它可以簡化為以下可編譯的可啟動代碼。但是,它不應該在編譯時失敗嗎?關于test2(),我們唯一可以確定的是它回傳Object或null,它是<V(extends Object)>,而不是<V extends IDummy>。為什么我能夠編譯它呢?
public class Main {
public static void main(String[] args) {
test(test2())。
}
private static void test(IDummy prop) {}。
private static <V> V test2(){
return null;
}
public interface IDummy {}。
}
uj5u.com熱心網友回復:
<V> V test2()說 "這是一個接受無界型別引數V并回傳該型別物件的方法"
讓我們先忽略一下這個方法的實作是什么樣子的(我們稍后會討論這個問題)。
所以如果你呼叫test(test2()),編譯器知道test2()的結果應該是一個IDummy。有什么方法可以確保這一點嗎?是的,有的:只要將IDummy作為具體的型別引數(Main.<IDummy>test2()將是明確的寫法,但編譯器會為你推斷)。
所以編譯器知道你想用IDummy來寫V,并自動為你做了這個。因此,整個陳述句可以編譯。
現在讓我們回到實作 test2()的問題上,以一種有意義的方式。實際上,只有兩種可能的方法來實作它:
null (因為這對于 V 可能代表的每個型別來說都是一個有效的值) 或者第二個選擇是類似于寫
的東西V value = (V) new Object() 。//或任何其他值。
return值。
這將在編譯時出現一個警告。這個警告基本上意味著泛型的型別保證被這個問題所破壞。
有時當你知道推斷的型別是通常正確的時候,這可能是有用的(例如,如果你有<V> V getProperty(String propertyName),那么只要每次呼叫都有正確的 propertyName/type 組合,它就真的能作業)。但這并不嚴格正確,你基本上是在要求編譯器 "相信我"。任何破綻都會導致運行時例外(最終很可能是一個ClassCastException)。
uj5u.com熱心網友回復:
我認為這是由于編譯的型別擦除造成的。 看一下類檔案,test2()方法應該回傳IDummy。 最后,我建議學習更多關于泛型的知識。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/318417.html
標籤:
