有没有办法在 EnumMap 中存储“可扩展枚举”?

ste*_*ver 3 java enums interface

我指的是 Joshua Bloch 在 Effective 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;
} 
Run Code Online (Sandbox Code Playgroud)

语法错误详情:

接口 java.util.Map 中的<K,V>方法不能应用于
所需的给定类型:capture#1 of ? 扩展 BaseEnum、WidgetData
找到:EnumOps1、WidgetData

Ste*_*ker 5

你的通配符有问题。您应该将您的地图声明为Map<BaseEnum, WidgetData>以及您的 EnumMap 为 ex。HashMap<BaseEnum, WidgetData>

有很多关于为什么这在 SO 上是正确的讨论,但请参阅什么是 PECS(生产者扩展消费者超级)?例如。

编辑

可悲的是,你是对的 - 你不能在那里使用 EnumMap 。这是因为您正在尝试使用一个接口,而 EnumMap 规定(因为它需要一个 type T extends Enum<T>)它只能是一个 Enum 。

您的选择基本上归结为

1) 使用 anEnumMap<EnumOps1,...>并失去多态性

2)使用 aHashMap<BaseEnum,...>一切正常,但您必须使用非枚举映射。

3)在尝试时使用通配符,但您会遇到我之前链接的 PECS 限制,例如您可以添加或删除元素,但不能同时添加或删除元素(supervs extends