我如何要求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(); } } 

然后我可以将MyWidgetMyWidget一些看起来很模糊的东西:

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

然后可以从MyInterface中的T型对象上的MyWidget调用getValue()方法。 问题当然是,“ <T extends Enum<T> extends MyInterface> ”是无效的语法。 有什么办法可以解决这个问题吗?

我不想让MyWidget<T extends MyInterface> ,因为T是一个枚举也是重要的。

提前致谢!

2 Solutions collect form web for “我如何要求generics参数是一个实现接口的枚举?”

使用' & '代替:

 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的。

  • 为什么C#不支持类构造函数中的genericstypes?
  • 我如何使用接口作为C#genericstypes约束?
  • 检查“T”是inheritance还是实现一个类/接口
  • 使用generics的c#协变返回types
  • 为什么Java的Class <T>是通用的?
  • 非generics类中的generics构造函数是否受支持?
  • C#语法 - 通过逗号将string拆分为数组,转换为通用列表和逆序
  • 该types必须是引用types才能在通用types或方法中将其用作参数“T”
  • 对于无效genericstypes参数的最佳例外
  • 如何获得genericstypesT的类实例
  • 为什么C#构造函数不能推断types?