2011-09-27 114 views
2

我試圖定義一般枚舉,但有與它的問題:是否可以創建泛型枚舉?

private enum Stick<T>{ 
    A, B, C; 

    private Stack<T> disks = new Stack(); 

    public void print(){ 
     System.out.println(this.name() + ": " + disks); 
    } 

    public T pop(){ 
     return disks.pop(); 
    } 

    public void push(T element){ 
     disks.push(element); 
    } 

}; 

是否有可能呢?

+2

你爲什麼想把堆棧放入一個枚舉? –

+0

爲什麼人們傾向於提出與該主題無關的問題? – damluar

+3

,因爲它與該主題有關。 – Bozho

回答

11

枚舉是常量。所以Stack disks不能是「任何類型的枚舉客戶端想要的堆棧」。它必須是固定的類型。

在枚舉中包含字段的要點是能夠保存關於每個元素的附加信息。例如,在堆棧的情況下,這可以是A("a", "b"),B("b", "c", "d")-每個元素指定在其堆棧中加載哪些項目(該示例需要可變參數構造函數)。但是他們的類型是嚴格規定的,不能是<T>

是Eclipse編譯器顯示的錯誤是明顯的:

語法錯誤,enum聲明不能有類型參數

然而,你可以做這樣的事情:

enum Foo { 
    A("foo", "bar"), 
    B(0, 1, 2); 
    private Stack<?> stack; 
    private <T> Foo(T... args) { 
     stack = new Stack<T>(); 
     stack.addAll(Arrays.asList(args)); 
    } 
    public <T> Stack<T> getStack() { 
     return (Stack<T>) stack; 
    } 
} 

然後:

Stack<String> stack1 = Foo.A.getStack(); 
Stack<Integer> stack2 = Foo.B.getStack(); 

System.out.println(stack1); 
System.out.println(stack2); 

結果:

[foo, bar] 
[0, 1, 2] 

更新:因爲你對你的目標的評論 - 河內塔不應該是枚舉,因爲他們的觀念正在轉變。相反,您應該使用枚舉作爲Map的鍵,其中的值是堆棧。我承認,使用枚舉域來做到這一點看起來很誘人,但這不是一個好習慣。枚舉更好地保持不變。當然,您可以使用上面的示例來實現您的初始目標,但我建議使用Map

+0

謝謝。我知道枚舉應該是不變的。但從技術上講,這是具有固定數量實例的同一類。所以它應該允許使用泛型。 – damluar

+0

@damular'T'是什麼類型?你不能用'new'運算符創建一個枚舉,所以你如何定義'T'的類型? – Thomas

+0

@ damluar你爲什麼想要你的棍子?堆棧?是枚舉常量? – entonio

0

不,但枚舉可以實現接口。可能會幫助你。

0

這可能是help。基本上,你需要這樣的:

public interface Stick<E extends Enum<E>>