2016-08-18 75 views
4

我試圖運行下面的代碼被JDK8感謝下編譯罰款類型推斷:JDK8類型推斷問題

public static <A,B> B convert(A a) { 
    return (B) new CB(); 
} 
public static void main(String[] args) { 
    CA a = new CA(); 
    CB b = convert(a); //this runs fine 
    List<CB> bl = Arrays.asList(b); //this also runs fine 
    List<CB> bl1 = Arrays.asList(convert(a)); //ClassCastException here 
} 

但是,在運行,這將引發ClassCastException異常:CB不能轉換爲[Ljava.lang .Object,但CB b = convert(a)正常工作。

任何想法爲什麼?

+3

等等,轉換甚至在做什麼?它的參數被忽略,所以傳入的內容並不重要。 – Carcigenicate

+1

您使用哪個JRE版本?我在1.8.0_92上得到了一個操作數棧上的java.lang.VerifyError:Bad type。順便說一句,使用類型見證對我有用:'List bl1 = Arrays.asList(Test。 convert(a));' –

+1

@StefanZobel確實有效,但我用了150次左右的用法並且手動更改並不容易 - 我希望JDK8能夠自動進行推理 –

回答

3

無論何時您創建一個帶有簽名的泛型方法,該簽名都會承諾返回調用者所希望的任何內容,這樣您就會遇到麻煩。你應該從編譯器得到一個「unchecked」警告,這基本上意味着:可能會出現意想不到的ClassCastException

你期望編譯器來推斷

List<CB> bl1 = Arrays.asList(YourClass.<CA,CB>convert(a)); 

而編譯器實際上推斷

List<CB> bl1 = Arrays.asList(YourClass.<CA,CB[]>convert(a)); 

據我知道,因爲它更不需要一個可變參數的包裝(這是兼容的方法調用pre-varargs代碼)。

這會失敗,因爲您的convert方法不會返回預期的數組類型。