2012-12-14 18 views
1

可能重複:
Cannot access static field within enum initialiser爲什麼我無法在構造函數中訪問枚舉中的靜態字段?

我的情況:

enum Attribute { POSITIVE, NEGATIVE } 
enum Content { 
    C1(Attribute.POSITIVE), 
    C2(Attribute.POSITIVE), 
    ... // some other positive enum instances. 
    Cm(Attribute.NEGATIVE), 
    ... // some other negative enum instances. 
    Cn(Attribute.NEGATIVE); 

    private final Atrribute a; 
    static int negativeOffset = 0; 
    private Content(Atrribute a) { 
     this.a = a; 
     if (a.compareTo(Attribute.POSITIVE) == 0) { 
       negativeOffset ++; 
     } 
    } 

    public static int getNegativeOffset() { return negativeOffset; } 
} 

我的目的是通過一個每當我添加一個新的枚舉(正屬性)來添加negativeOffset,那麼我可以調用getNegativeOffset()來獲得負數 enum的起始點並執行任何我想要的操作。

但comlier抱怨

Cannot refer to the static enum field Content.negativeOffset within an initializer

+0

HTTP的Attribute枚舉值的簡單比較:// stackoverflow.com/questions/536449/cannot-refer-to-the-static-enum-field-within-an-initializer 這將有所幫助。 – LPD

回答

2

您可以使用此 「絕招」:

private static class IntHolder { 
    static int negativeOffset; 
} 

然後參考變量是這樣的:

IntHolder.negativeOffset ++; 

return IntHolder.negativeOffset; 

這個原理的工作原理是,JVM保證當初始化靜態內部類時初始化變量,直到它被訪問纔會發生。然後

整個類將是如下,其中編譯:

enum Attribute { POSITIVE, NEGATIVE } 
enum Content { 
    C1(Attribute.POSITIVE), 
    C2(Attribute.POSITIVE), 
    ... // some other positive enum instances. 
    Cm(Attribute.NEGATIVE), 
    ... // some other negative enum instances. 
    Cn(Attribute.NEGATIVE); 

    private final Attribute a; 

    private static class IntHolder { 
     static int negativeOffset; 
    } 

    private Content(Attribute a) { 
     this.a = a; 
     if (a == Attribute.POSITIVE) { 
       IntHolder.negativeOffset ++; 
     } 
    } 

    public static int getNegativeOffset() { return IntHolder.negativeOffset; } 
} 

注意的拼寫錯誤更正和使用的==代替compareTo()

+0

謝謝,不錯的技巧!我沒想到這個線程安全技巧也適用於這裏!順便說一句,我仍然想知道爲什麼原始方法不起作用。靜態fileld初始化是否在構造函數之前發生? – larmbr

+0

你的問題是枚舉在實例之前不能有任何聲明,這意味着你不能初始化(或使用)實例構造函數需要的任何靜態字段。但是,通過將該字段置於* another *類(儘管是內部靜態類)中,另一個類將在構造函數中的第一個用法上加載(並進行靜態初始化)。這種模式是一種非常好的方式 - 線程安全地懶惰初始化單例*而不進行任何同步。 – Bohemian

相關問題