我如何要求generics参数是一个实现接口的枚举?
我并不是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
重MyWidget
一些看起来很模糊的东西:
public class MyWidget<T extends Enum<T> extends MyInterface> { ... }
然后可以从MyInterface
中的T
型对象上的MyWidget
调用getValue()
方法。 问题当然是,“ <T extends Enum<T> extends MyInterface>
”是无效的语法。 有什么办法可以解决这个问题吗?
我不想让MyWidget<T extends MyInterface>
,因为T是一个枚举也是重要的。
提前致谢!
使用' &
'代替:
public class MyWidget<T extends Enum<T> & MyInterface> { ... }
JLS称之为“交集types”,但在Java教程中我没有发现它。 我只是说,它确实是你希望“ extends
”会做的。
另外,我应该提到,在交集types中可以有任意多的types。 所以如果你想要的话,你可以这样做:
public class MyWidget<T extends Enum<T> & MyInterface & Serializable & Cloneable> { ... }
[注意:此代码示例不应被解释为对Cloneable
接口的认可; 当时只是方便而已。]
用于JDK 7的JSR 203(新的新IO)使用了很多实现接口的枚举(例如: http : //openjdk.java.net/projects/nio/javadoc/java/nio/file/FileVisitOption .html )允许他们在未来的一些摆动空间,为未来额外的枚举选项集。 所以这是一个可行的方法,显然是在一个大型的Sun项目中经过深思熟虑之后select的。