2015-04-14 70 views
0

我試圖實例添加到以下EnumMap的:添加泛型類型,以EnumMap的

class ActiveG<D extends GData, T extends GTemplate> { 

    EnumMap<GStateType, GState<ActiveG<D,T>> map; 
    .. 
    .. 
} 

class TGData extends GData {...} 
class TGTemplate extends GTemplate {....} 

class ActiveTG extends ActiveG<TGData, TGTemplate> { 

    // fails with compilation error 
    super.states.put(GStateType.WAITING, new TGWaitingState<ActiveTG>(this)); 
    ... 
    ... 
} 

的錯誤,我得到:

The method put(GStateType, GState<ActiveG<TGData,TGTemplate>>) in the 
type EnumMap<GStateType,GState<ActiveG<TGData,TGTemplate>>> is not 
applicable for the arguments (GStateType, TGWaitingState<ActiveTG>) 

任何人都可以盡力幫助我弄清楚發生了什麼失蹤讓它起作用?? 謝謝!

+1

'EnumMap '?你想做什麼?你在某處是否有一些'enum Long {}',或者你想在'EnumMap'中使用'java.lang.Long'作爲鍵?實際上,代碼示例沒有任何意義,因爲您調用了'super.states.put',但您向我們展示了'EnumMap <...> map'的聲明。請澄清併發布重現錯誤的正確代碼。 http://stackoverflow.com/help/mcve – Radiodef

+0

當然...你的地圖不是GStateType,TGWaitingState 類型:)。您已將地圖定義爲Long,GState <...>,其中GStateType和TGWaitingState <>是什麼? – jiveturkey

+0

對不起,做了一個壞的複製粘貼 - 現在看看它。順便說一句,TGWaitingState繼承了GState。 – Shvalb

回答

1

簡而言之,Java中的泛型不是協變的。

例如如果你有

class Parent {...} 

class Child extends Parent {...} 

Foo<Child>沒有一個Foo<Parent>

回到你的代碼:

ActiveTG您枚舉映射期待GState<ActiveG<TGData,TGTemplate>>的價值,但你給它一個TGWaitingState<ActiveTG>,這是一個GState<ActiveTG>

雖然ActiveTG是-a ActiveG<TGData,TGTemplate>,GState<ActiveTG>不是GState<ActiveG<TGData,TGTemplate>>

爲了解決這個問題,就需要在類型PARAMS頗有些變化,像

class ActiveG<D extends GData, 
       T extends GTemplate, 
       E extends ActiveG<D,T>> { 
    EnumMap<GStateType, GState<E>> map; 
} 

或只是讓mapEnumMap<GStateType, GState<? extends ActiveG<D,T>>類型。這在某些情況下可能不會奏效,例如,您需要檢索結果爲GState<ActiveTG>而不是GState<ActiveG<D,T>>

+0

謝謝你的詳細解答!我從你身上學到了一些新東西! – Shvalb