2009-07-01 117 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