2015-04-02 15 views
6

工作,我有這樣的類型:方法類型參數不適合循環

abstract class ControlGraphic { 
    //... 
} 

class PrecisionControlGraphic extends ControlGraphic { 
    //... 
} 

class AccuracyControlGraphic extends ControlGraphic { 
    //... 
} 

我有一個返回值的方法的List<T>,其中T是依賴於類型參數PrecisionControlGraphicAccuracyControlGraphic

private <T extends ControlGraphic> List<T> getGraphics() { 
    List<T> graphics = new LinkedList<T>(); 
    for (ControlGraphic graphic : getGraphicsFromDB()) 
    graphics.add((T) graphic); 
    return graphics; 
} 

以下代碼正常工作:

List<PrecisionControlGraphic> precisionGraphics = getGraphics(); 
for (PrecisionControlGraphic graph : precisionGraphics) { ... } 

我想知道爲什麼這個另一個不:

for (PrecisionControlGraphic graph : getGraphics()) { ... } 

謝謝。

+7

在你的第二個例子中,編譯器不知道T使用什麼類型。您需要指定它,例如(PCG graph:this。 getGraphics()' – 2015-04-02 07:37:49

+1

@AdrianLeonhard你爲什麼決定將它發佈爲評論而不是回答? – Pshemo 2015-04-02 07:39:31

+2

@Pshemo懶惰。 – 2015-04-02 07:40:31

回答

5

方法簽名是說「您可以將T設置爲ControlGraphic的任何子類」,這就是賦值類型檢查的原因(因爲編譯器找到一個可用的類型T,實際上類型是從指定的變量)。

「其他」(直接循環)不起作用,因爲類型T可以是ControlGraphic的任何子類,不一定是PrecisionControlGraphic。直接循環不起作用,因爲Java中的類型檢查器不像函數式編程語言那樣進行完全推理。 「圖形」變量的類型必須實際上是「ControlGraphic的任何子類」才能被接受(並且實際上可以通過使該類型成爲封閉方法的類型參數來進行安排)。

另一種可能性,正如@Adrian萊昂哈德指出的是將呼叫註釋到getGraphics與所需類型:

for (PCG graph : this.<PCG>getGraphics())

但是,基本上,任何與這些解決方案,您在不當使用泛型。在getGraphics中所有你知道的就是你正在處理ControlGraphic對象,所以這個方法應該返回List<ControlGraphic>,你的代碼應該在已知派生類型的代碼的地方執行顯式的強制轉換。

+0

我明白了,謝謝:)這很好,你用Adrian Leonhard的解決方案編輯你的問題(見評論)。 – 2015-04-02 07:47:19

+1

@bigdestroyer完成。順便說一句好問題。 – Atsby 2015-04-02 07:55:58

相關問題