1

int[] 配列を enum のすべてのインスタンスで共有したいとします。ここに例があります

public enum SampleEnum {
    Enum1(1), Enum2(2), Enum3(3), Enum4(4);

    private int[] values;

    private static final int[] SharedValues = {1, 2, 3, 4, 5};
    private static final int ValueCount = SharedValues.length;

    private SampleEnum(int factor) {
        // I prefer to calculate data once within constructor
        values = new int[ValueCount];
        for (int i=0; i<ValueCount; i++)
            values[i] = SharedValues[i] * factor;
    }

    private int[] getValues() {
       return values;
    }    
}

推測: ValueCount と SharedValues の両方について、「初期化子内の静的列挙型フィールドを参照できません」というメッセージが表示されます。

この問題は、静的配列を別のクラスに配置することで解決できます。

class SampleEnumData {
    static final int[] SharedValues = {1, 2, 3, 4, 5};
}


public enum SampleEnum {
    Enum1(1), Enum2(2), Enum3(3), Enum4(4);

    private int[] values;

    private SampleEnum(int factor) {
        // I prefer to calculate data once within constructor
        int[] sharedValues = SampleEnumData.SharedValues;
        int valueCount = sharedValues.length;
        values = new int[valueCount];
        for (int i=0; i<valueCount; i++)
            values[i] = sharedValues[i] * factor;
    }

    private int[] getValues() {
       return values;
    }    
}

しかし、これは論理的な解決策というよりも、ぎこちないパッチのように見えます。

列挙型初期化子内で静的クラスへの参照を許可しない理由はありますか?

4

2 に答える 2

3

列挙型初期化子内で静的クラスへの参照を許可しない理由はありますか?

これは、アクセスが許可されていない静的フィールドであり、非常に正当な理由があります。列挙型メンバーは、後の静的フィールド初期化子の前に初期化されるため、フィールドには初期値が保持されます。これは、列挙型のいくつかの側面によってキー付けされたマップを生成しようとしている場合に問題になることがよくあります。実際にはコンストラクターで生成を実行したいのですが、マップがまだ作成されていないため実行できません。

オプション:

  • valuesすべてのインスタンスが構築された後に実行される静的初期化ブロックですべての初期化を実行します。ここでの問題は、フィールドを final にしたい場合は、最初に配列を作成する必要があるということです。つまり、データにアクセスせずに、配列の大きさを知る必要があります。(名前の選択は、values()ここでも利用可能な方法を考えると残念です。念のため。)
  • ネストされたプライベート クラスを静的フィールドの初期化の「ホルダー」として使用します。これは 2 番目のソリューションに似ていますが、クラスを公開していません。

正直なところ、後者のアプローチはおそらく最も単純です。

public enum SampleEnum {
    ...

    private static class SampleEnumData {
        static final int[] SHARED_VALUES = {1, 2, 3, 4, 5};
    }
}
于 2013-10-21T06:06:22.437 に答える