我正在尝试将实例添加到以下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>)


任何人都可以尝试帮助我找出使它正常工作所缺少的东西吗?
谢谢!

最佳答案

简而言之,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>>

为了解决这个问题,您将需要对类型参数进行一些更改,例如

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


或简单地将map设置为EnumMap<GStateType, GState<? extends ActiveG<D,T>>类型。在某些情况下,这可能无法很好地工作,例如,您需要以GState<ActiveTG>而不是GState<ActiveG<D,T>>的形式检索结果

10-06 02:22