我正在尝试将实例添加到以下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>)
任何人都可以尝试帮助我弄清楚缺少什么让它起作用吗? 谢谢!
答案 0 :(得分:1)
简而言之,Java中的泛型不是协方差。
e.g。如果你有
class Parent {...}
class Child extends Parent {...}
Foo<Child>
不是Foo<Parent>
回到你的代码:
ActiveTG
中的枚举地图需要GState<ActiveG<TGData,TGTemplate>>
作为值,但您要给它TGWaitingState<ActiveTG>
,这是GState<ActiveTG>
。
虽然ActiveTG
是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>>