2017-03-10 166 views
1

爲什麼它不起作用?Java泛型 - 編譯錯誤

class W<A extends Number> 
    { 
     public void create(A value) 
     { 

     } 
    } 

    public void calculate(W<? extends Number> w) 
    { 
     Integer v = 5; 
     w.create(v); // Compilation error 
    } 

有人能解釋那個代碼有什麼問題,以及如何解決它?

編譯錯誤:「創建(捕獲)以W不能應用於(java.lang.Integer中)」

+2

郵政錯誤消息請。 – shmosel

+0

創建(捕捉<?擴展java.lang.Number中>)以W不能應用於(java.lang.Integer中) – Yeynno

+3

請[編輯]您發佈的內容包括相關的信息。 – shmosel

回答

1

在此之前,直接從核心仿製藥的原則。當您使用? extends SomeType時,您不能通過/消耗任何東西轉換爲參考,因爲這可能違反了檢索這些項目時由泛型提供的類型安全保證。那麼人們將能夠做的事情 -

List<Long> longs = Arrays.asList(5L, 10L, 20L); 
List<? extends Number> numbers = longs; 


// Trouble! 
numbers.add(10.5); 

見我的博客文章here對亞型與泛型是如何工作的細節之一。

-1

這兩個對象應該擴展號碼,但並不意味着這些對象不能是兄弟姐妹:

  • ClassA的擴展號碼{..}
  • ClassB的擴展號碼{..}

ClassA不能被轉換爲ClassB,這就是可能發生在您的代碼中。它既可以是ClassA,但是你的編譯器不能確定它,因爲它可能是ClassB或任何其他擴展Number的類,所以它會給出編譯錯誤。

+1

這沒有任何意義,他不延長java.lang.Number中,他宣稱是通配符「A」在W.java文件 –

+1

是的,這應該延長數的類型。我顯示爲一類通用 –

+0

我可以看到你的意思,但我想它可能不會很清楚有人喜歡OP誰不知道如何在第一時間:) –

2

您對泛型中的通配符有一個常見的誤解。你認爲?意味着你可以通過任何類型(只要它延伸Number),但你不能。

? extends Number並不意味着您可以通過任何類型的延伸Number。這意味着「一個特定的,但未知的類型,延伸Number」。由於編譯器確切的類型是未知的,因此它不能讓你使用Integer--那時編譯器根本沒有足夠的信息來檢查它是否是類型安全的。 (它不知道您傳遞給該方法的W的實際類型是Integer還是其他類型的Number)。

這與您爲什麼不能向List<?>添加任何內容的原因完全相同,例如,這是人們經常問的問題。

+2

泛型函數當被要求經常,我想知道你爲什麼不把這個問題複製到這些現有的問題之一:-) – GhostCat

0

您可以使用bounderies在創建方法:

public <T extends Number> void create(final T value) { 

} 

例子:

class W<A extends Number> { 
    public <T extends Number> void create(final T value) { 

    } 

    public void calculate(final W<? extends Number> w) { 
     final Integer v = 5; 
     w.create(v); // Compilation error 
    } 
} 
0

你必須聲明你使用它之前,什麼樣的W使您正在使用的

public void calculate(W<? extends Number> w) { 
    Integer v = 5; 
    new W<Integer>().create(v); 
} 

或者,您可以更改創建方法接受任何NU MBER

public void create(Number value) { 

}