1

重複の可能性:
列挙型初期化子内の静的フィールドにアクセスできません

私の状況:

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; }
} 

私の意図は、新しい列挙型 (POSITIVE 属性を持つ) を追加するたびに、negativeOffset を 1 つずつ追加することです。その後、getNegativeOffset() を呼び出して、負の列挙型の開始点を取得し、必要なことを行うことができます。

しかし、comlier は次のように不満を述べています。

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

4

1 に答える 1

2

この「トリック」を使用できます。

private static class IntHolder {
    static int negativeOffset;
}

次に、次のように変数を参照します。

IntHolder.negativeOffset ++;

return IntHolder.negativeOffset; 

これが機能する理由は、IntHolder静的内部クラスが初期化されるときに変数が初期化されることを 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; }
}

スペルミスの修正と、代わりにAttribute使用する列挙値との単純な比較に注意してください==compareTo()

于 2012-12-14T04:56:34.577 に答える