【问题标题】:How can I require a generic parameter to be an enum that implements an interface?如何要求泛型参数是实现接口的枚举?
【发布时间】:2009-07-01 18:44:09
【问题描述】:

我不是 100% 相信这是一个好主意,但我今天遇到了一些代码,目前实现如下:

class MyWidget <T extends Enum<T> > {
  MyWidget(Map<T, Integer> valueMap) {
    mValueMap = valueMap;
  }

  Map<T, Integer> mValueMap;
}

其中MyWidget 然后提供使用mValueMap 将传入的Enum 转换为Integer 或从Integer 转换的方法。

我正在考虑做的是尝试重构它,以便我声明我的枚举:

interface MyInterface {
  public Integer getValue();
}

enum MyEnum implements MyInterface {
  foo, bar;
  public Integer getValue() {
    return ordinal();
  }
}

然后我就可以将MyWidget 重写为看起来像这样的东西:

public class MyWidget<T extends Enum<T> extends MyInterface> {
  ...
}

然后就可以在MyWidget 内的T 类型对象上从MyInterface 调用getValue() 方法。当然,问题在于“&lt;T extends Enum&lt;T&gt; extends MyInterface&gt;”不是有效的语法。有没有办法解决这个问题?

我不想只有MyWidget&lt;T extends MyInterface&gt;,因为 T 是一个枚举也很重要。

提前致谢!

【问题讨论】:

    标签: java generics enums


    【解决方案1】:

    改用“&amp;”:

    public class MyWidget<T extends Enum<T> & MyInterface> {
        ...
    }
    

    JLS 将此称为“交集类型”,但我在 Java 教程中找不到任何提及。我只想说它完全符合您希望 "extends" 会做的事情。

    另外,我应该提到,您可以在交集类型中拥有任意数量的类型。所以如果你愿意,你可以这样做:

    public class MyWidget<T extends Enum<T> & MyInterface & Serializable & Cloneable> {
        ...
    }
    

    [注意:此代码示例不应被视为对Cloneable 接口的认可;它当时只是很方便。]

    【讨论】:

    • & 语法很简洁,但我发现使用它通常会产生代码异味,这表明你的模型有些地方不太对劲。
    • 我倾向于同意(我想我可能用过一次或两次,如果那样的话)。但在枚举实现接口的情况下,我认为是合适的。
    • 谢谢。你的帖子不知何故让我意识到,我真正需要的是……doSomething(Enum&lt;? extends SomeInterface&gt;)
    • @skaffmann 如果你有时间分享你的 WRT 相关经验代码味道,我真的很感激
    • +10 我自己永远也想不通。使用接口处理枚举的唯一方法。
    【解决方案2】:

    JDK 7 的 JSR 203(新的新 IO)东西大量使用实现接口的枚举(例如:http://openjdk.java.net/projects/nio/javadoc/java/nio/file/FileVisitOption.html),以便它们在未来有一些回旋余地,以便将来使用更多的枚举选项集.所以这是一种可行的方法,显然是在一个大型 Sun 项目中经过深思熟虑后选择的。

    【讨论】:

    • 整洁。希望 java 7 能在我的胡子变灰之前出现。
    • 从编写少量代码使用这些东西,我的印象是它有点奇怪。不能说我在别的地方见过。我敢肯定,名称中带有 7 的东西将在 2010 年发布。我不知道它是否会是 JCP 认可的“Java 7”。现在只有甲骨文可以回答这个问题......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-16
    • 1970-01-01
    相关资源
    最近更新 更多