如何将泛型参数作为实现接口的枚举?

时间:2009-07-01 18:44:10

标签: java generics enums

我并非100%确信这是一个好主意,但我今天碰到了一些目前实现的代码:

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

  Map<T, Integer> mValueMap;
}

其中MyWidget然后提供使用mValueMap将传入的Enum转换为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> {
  ...
}

然后可以在getValue()上的MyInterface调用T方法 - 在MyWidget中输入对象。当然,问题是“<T extends Enum<T> extends MyInterface>”不是有效的语法。有没有办法解决这个问题?

我不想只有MyWidget<T extends MyInterface>,因为T是枚举也很重要。

提前致谢!

2 个答案:

答案 0 :(得分:83)

改为使用“&”:

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

JLS将此称为“交集类型”,但我在Java教程中找不到它。我只是说它完全符合你希望“extends”所做的那样。

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

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

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

答案 1 :(得分:1)

JDK 7的JSR 203(新的新IO)正在大量使用实现接口的枚举(例如:http://openjdk.java.net/projects/nio/javadoc/java/nio/file/FileVisitOption.html),以便将来有一些摆动空间用于将来的其他附加设置枚举选项。所以这是一种可行的方法,显然是在一个大型Sun项目中经过深思熟虑后选择的方法。