我指的是约书亚·布洛赫(Joshua Bloch)的《有效Java》第34项中的范例。我想采用他使用的方法,即让每个相关的enum
实现一个基本接口,并从“子枚举”中初始化一个EnumMap
。请参阅下面的代码部分。我收到了我不理解的语法错误。我没有设置这种实现方法,但是我想了解为什么它不起作用。
请注意,此示例假定每个类定义都在其自己的文件中。
public interface BaseEnum {
...
}
public enum EnumOps1 implements BaseEnum {
...
}
public class Widget {
public Widget() {
regMap = new EnumMap<EnumOps1, WidgetData>(EnumOps1.class);
for (EnumOps1 op : EnumOps1.values()) {
regMap.put(op, getWidgetData(op.key())); // line with syntax error
}
}
protected Map<? extends BaseEnum, WidgetData> regMap;
}
语法错误详细信息:
接口java.util.Map
<K,V>
中放置的方法不能应用于给定类型必填:第1个,共?个扩展BaseEnum,WidgetData
找到:EnumOps1,WidgetData
最佳答案
通配符有问题。您应该将地图声明为Map<BaseEnum, WidgetData>
,还应将EnumMap声明为ex。 HashMap<BaseEnum, WidgetData>
关于在SO上为什么如此的原因有很多讨论,但请参见What is PECS (Producer Extends Consumer Super)?。
编辑
遗憾的是,您是对的-您不能在此处使用EnumMap。这是因为您正在尝试使用接口,并且EnumMap规定(因为它需要输入T extends Enum<T>
类型)它必须只能是Enum。
您的选择基本上归结为
1)使用EnumMap<EnumOps1,...>
失去多态性
2)使用HashMap<BaseEnum,...>
,一切正常,但必须使用非枚举映射。
3)在尝试使用通配符时,您会遇到我之前链接的PECS限制,例如您可以添加或删除元素,但不能同时添加或删除元素(super
与extends
)