2012-04-10 75 views
4

我絆倒以下問題,我無法通過此類是用Java 1.5(java.lang包)爲什麼不從枚舉延伸<E延伸枚舉<E>>

public abstract class Enum<E extends Enum<E>> {... 
}.. 

限定擴展和實現我遇到的問題是創建我自己的具有不同序數值的枚舉類型。我不想使用getCode()等不同的名稱來實現它,所以我認爲我可以繼續擴展上面的類。

public final class XYZ extends Enum<XYZ> { //Does not work. 
    // 
    A("A", 1), 
    B("B", 7); 
    . 
} 

我知道我可以做到以下幾點:

public enum NEWEnum { 
    A(1), 
    B(7); 

    private int code; 
    private NEWEnum(int code) { 
    this.code = code; 
    } 
    public int getCode() { 
    return this.code; 
    } 
} 

我寧願在枚舉的像序()和名稱(),而不是通常namings。

+0

@RayToal我知道'ordinal'和'name'是最終的。問題是爲什麼我不能從上面的Enum類擴展..如果我可以擴展,我應該能夠調用具有'name'和'ordinal'參數的受保護的構造函數。 – khmarbaise 2012-04-10 08:24:13

回答

5

你不能像這樣擴展Enum。它內置於編譯器或運行時(不知道哪個)。

但它看起來像你試圖解決錯誤的問題;枚舉值的序數不應具有任何功能意義。只要你給它一個,它應該有一個不同於'Ordinal'的名字。你的第二個代碼片段遠遠優於你的第一個代碼片段。

一般情況下,依靠依次爲東西是不好的做法;它可能永遠不會被暴露在第一位。你唯一可以依靠的是名字,以及你自己賦予的任何價值。

如果它是對你很重要命名您的字段「序」,只需使用typesafe enum pattern (item 21),這枚舉僅僅是一種實現。

+0

我知道依靠ordinal()是不好的做法,但我有遺留代碼,我必須應付它。所以我必須去枚舉模式。 – khmarbaise 2012-04-10 08:37:56

4

枚舉由編譯器得到特殊待遇,並像EnumSet類基於這種治療做出假設。像ordinal()name()這樣的Enum方法的行爲是嚴格定義的,並且自己實施它們來複制這種行爲是沒有意義的。此外,聲明枚舉值的語法僅在enum中有效,並且不會在class中編譯。

重要的是要記住,你不應該使用ordinal()自己,所以其定義以滿足您的問題沒有任何意義是非常重要的。

+0

我不想實現ordinal()既不是name()new。我只是不能從抽象的Enum類擴展,這似乎是不可能的。 ordinal()的問題是我有遺留的代碼,我必須兼容。我不想擺脫序數(),但目前我沒有機會。 – khmarbaise 2012-04-10 08:35:21

+0

@khmarbaise在java中獲得具體的有序()值的唯一方法是對枚舉值進行排序,也許會添加填充值 - 第一個值爲0,然後是1,...(這就是沒有人直接使用ordinal()的原因)。唯一的另一種方法是在用ASM或BCEL編譯後修改生成的字節碼(從來沒有做過,也可能很複雜)。 – josefx 2012-04-10 08:47:54

1

Enum類是特殊在Java中,因爲它是用來實現枚舉的語言功能。因此它不僅僅是像Java中任何其他類一樣的類,而是更特殊的類(比如String,其中+運算符被重載,或像裝箱類)。對於這些功能的工作,需要特殊要求的枚舉(如,我猜,連續序數)。因此,Java語言規範explicitly forbids手動繼承Enum類。

0

枚舉在語言核心和特殊用途中有特殊的含義。因此,您可以在switch語句中使用它們,這對於普通類是不可能的。

0

例如,如果你明確地實現它,你不必初始化「名」,並在構造函數「序」的財產。它可能會導致NPE。

相關問題