2012-02-13 76 views
12

使用枚舉我有一個枚舉泛型在Java中

public enum Days { 
SUNDAY, MONDAY, TUESDAY, WEDNESDAY, 
THURSDAY, FRIDAY, SATURDAY 

}

我想使一個類可以採取的類型天值。所以我用Java泛型

public class State<T extend Days> 

但有一個錯誤

The type parameter T should not be bounded by the final type Days. 
Final types cannot be further extended 

我該如何解決?

回答

6

不要使用綁定一個仿製藥。沒有必要。只要使用無界類型,像這樣:

public class State<T> { 
    public State(T startState) { 
     // whatever 
    } 
} 

,並使用它:

State<Days> dayState = new State<Days>(Days.SUNDAY); 

這是不需要綁定一個簡單的類型類。

唯一的約束,且可能是有意義的是綁定到一個enum

public class State<T extends Enum<T>> { 
    public State(T startState) { 
     // whatever 
    } 
} 

此版本需要泛型參數是enum。在這個版本上使用示例仍然編譯,但這不會(例如)編譯:

State<String> dayState = new State<String>("hello"); 

因爲String不是enum

+7

這不是OP想要的。 OP只想接受天,而不是任何東西或任何枚舉。他不需要泛型就可以做到這一點,他根本不需要使用泛型。 – Malcolm 2012-02-13 12:35:01

+0

@Malcolm嗯,他可以爲他的'State'類使用泛型(按照我的代碼)。他只是不需要泛型就是有界的。我明白你的意思,但他*可以讓他的班級變得通用 - 這似乎是一個方便的班級,可以處理初始/當前狀態 – Bohemian 2012-02-13 19:22:59

+1

它不符合OP指定的目的。他需要一個在Days或其子女上工作的課程:「我想創造一個能夠接受類型天數值的課程」。由於任何枚舉都沒有孩子,所以他應該明確寫出Days。您的代碼不會將這些值限制爲Days。 – Malcolm 2012-02-13 19:28:36

5

您不能在java中擴展枚舉(http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html到最後)。因此是不可能的。

- 如果您需要您的類只與你的枚舉工作,你並不需要仿製藥

- 如果不是你需要它與其他枚舉工作(它是有道理的?)你不需要指定擴展。

你的州立班究竟做了什麼?

9

枚舉是最後的類型,這意味着,你不能從他們

通用延長像想一類作爲參數,它是天或擴展類,而是擴展的類是不可能

所以唯一可能的參數是天,你並不需要一個通用的,如果只有一個值可能

+1

-1您在這裏錯過了重點。任何類型都是可能的 - 這是一個通用的州級課程。 – Bohemian 2012-02-13 12:13:28

+0

@Bohemian不,我認爲你是錯過了這一點。看到你的答案評論。 – Malcolm 2012-02-13 12:35:37

2

這對我來說編譯Java 6的下罰款:

public enum Days { 
    SUNDAY, 
    MONDAY, 
    TUESDAY, 
    WEDNESDAY, 
    THURSDAY, 
    FRIDAY, 
    SATURDAY 
} 

public class State<T extends Days> { 
    T state; 

    public State(T startState) { 
    this.state = startState; 
    } 
} 

private void test() { 
    State<Days> state = new State<Days> (Days.MONDAY); 
} 

但是,如果你希望你的State對象從一個enum切換到另一個你會更好地使用這樣的:

public class State<S extends Enum<S>> { 
    final ArrayList<S> states = new ArrayList<S>(); 
    private S state; 

    public State(S startState) { 
    states.addAll(EnumSet.allOf(startState.getClass())); 
    this.state = startState; 
    } 

    public S next() { 
    return state = states.get((state.ordinal() + 1) % states.size()); 
    } 

    public S prev() { 
    return state = states.get((state.ordinal() - 1 + states.size()) % states.size()); 
    } 

    public S set(S newState) { 
    return state = newState; 
    } 

    public S get() { 
    return state; 
    } 
} 

private void test() { 
    State<Days> state = new State<Days> (Days.MONDAY); 
    // ... 
} 
+0

'this.states =(S [])states.toArray();'拋出'ClassCastException'!我正在研究解決方案。 – OldCurmudgeon 2012-02-13 13:14:37

+0

修復了'ClassCastException'問題! – OldCurmudgeon 2012-02-13 13:28:16

+0

但S仍然可以是任何枚舉,它不一定是'Days'枚舉... – FBB 2015-09-03 08:52:45

5

在這裏做的事情是

public enum Days{..} 

public class State { // no generic argument! 
    ... 
} 

既然這樣,你不能有State<T extends Days>因爲滿足T extends Days的唯一途徑是讓TDays。這就是Daysfinal

因此,相反,你應該讓State通用,並且使用Days直接無處不在,你試圖使用T。你不能聲明public class State<Days>,因爲它會嘗試將Days作爲變量類型,不作爲Days類別,那就是而不是你想要什麼。