如何要求泛型参数是实现接口的枚举?
Posted
技术标签:
【中文标题】如何要求泛型参数是实现接口的枚举?【英文标题】: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()
方法。当然,问题在于“<T extends Enum<T> extends MyInterface>
”不是有效的语法。有没有办法解决这个问题?
我不想只有MyWidget<T extends MyInterface>
,因为 T 是一个枚举也很重要。
提前致谢!
【问题讨论】:
【参考方案1】:改用“&
”:
public class MyWidget<T extends Enum<T> & MyInterface>
...
JLS 将此称为“交集类型”,但我在 Java 教程中找不到任何提及。我只想说它完全符合您希望 "extends
" 会做的事情。
另外,我应该提到,您可以在交集类型中拥有任意数量的类型。所以如果你愿意,你可以这样做:
public class MyWidget<T extends Enum<T> & MyInterface & Serializable & Cloneable>
...
[注意:此代码示例不应被视为对Cloneable
接口的认可;它当时只是很方便。]
【讨论】:
& 语法很简洁,但我发现使用它通常会产生代码异味,这表明你的模型有些地方不太对劲。 我倾向于同意(我想我可能用过一次或两次,如果那样的话)。但在枚举实现接口的情况下,我认为是合适的。 谢谢。你的帖子不知何故让我意识到,我真正需要的是……doSomething(Enum<? extends SomeInterface>)
@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”。现在只有甲骨文可以回答这个问题...... docs.oracle.com/javase/8/docs/api/java/nio/file/…以上是关于如何要求泛型参数是实现接口的枚举?的主要内容,如果未能解决你的问题,请参考以下文章