2016-02-26 133 views
0

我在(B)行得到編譯錯誤「AlphaData無法通過方法調用轉換轉換爲CAP#1」。我的解決方法是將line(A)處的indexOf()的簽名更改爲Object類型而不是T.但是,然後我失去了類型檢查。此外,如果「數據」也被聲明爲BetaData類型,我想讓B行工作。有沒有辦法做我想要的?Java:使用具有通配符類型參數的類函數

public class Test 
{ 
    class AlphaData {} // base class for data 

    class BetaData extends AlphaData {} // subclass for data 

    abstract class BasicAdapter<T> // a generic adapter 
    { 
    abstract int indexOf (T item); //(A) 
    } 

    class BetaAdapter extends BasicAdapter<BetaData> // adapter subclass with binding 
    { 
    int indexOf (BetaData item) { return 0; } 
    } 


    BasicAdapter<? extends AlphaData> adapter = null; 

    Test() 
    { 
    AlphaData data = null; 
    int index = adapter.indexOf (data); //(B) -- compile error here 
    } 
} 
+2

你如何實例化適配器? –

+0

寫入的示例只允許一個實例:new BetaAdapter()。但是它需要爲BasicAdapter的其他子類以及BetaAdatper的子類工作。 –

回答

3

adapter.indexOf不能安全地傳遞了一個AlphaData,因爲它可能具體是BasicAdapter<BetaData>;儘管data具體可以是BetaData的實例,但它可以是普通的AlphaData或任何其他不相關的子類AlphaData

縮寫要記住的是佩奇

  • 生產者extend
  • 消費者super

你想adapter消耗AlphaData,所以你需要一個BasicAdapter<? super AlphaData>

2

這是正常現象。

BasicAdapter<? extends AlphaData> adapter = null 

聲明adapter是某種類型的擴展AlphaDataBasicAdapter但它可以是任何類型的,所以T = any type that extends AlphaData。因此,當你調用

AlphaData data = null; 
int index = adapter.indexOf (data); //(B) -- compile error here 

你給一個AlphaData參數,所以它不符合「的東西是一個AlphaData」:這可能是例如BetaData

如果你想讓它對於任何AlphaData工作,只需使用:

BasicAdapter<AlphaData> adapter = null; 

不使用通配符,或

BasicAdapter<? super AlphaData> adapter = null; 

這將編譯如果dataAlphaDataBetaData

相關問題