2009-07-01 73 views
39

我不是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> { 
    ... 
} 

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

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

在此先感谢!

回答

77

使用“&”,而不是:

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

JLS称此为一个“交集型”,但我能找到在Java教程没有提到它。我只是说,它确实是你所希望的“extends”会做的。

此外,我应该提到,你可以有任何多种类型,你想在交集类型。所以,如果你愿意,你可以这样做:

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

[注:此代码示例不应该被解释为Cloneable接口的认可;这在当时仅仅是方便]

+0

&语法很整洁,但是我发现使用它通常会变成代码异味,并且表明某个东西不适合您的模型。 – skaffman 2009-07-01 19:33:09

+2

我倾向于同意(如果是这样的话,我想我已经使用了它一次或两次)。但在枚举实现接口的情况下,我认为它是适当的。 – 2009-07-01 19:41:46