2012-10-22 14 views
8

私はそれを知る唯一の人かどうか分かりませんが、enumの値は暗黙的に最終的なものではなく、変更することができます。Java enumsの可用性の可能性と可能性?

enum EnumTest { 
    TOTO("TOTO 1"), 
    TATA("TATA 2"), 
    ; 

    private String str; 

    private EnumTest(String str) { 
     this.str = str; 
    } 

    @Override 
    public String toString() { 
     return str; 
    } 
    } 

    public static void main(String[] args) { 
    System.out.println(EnumTest.TATA); 
    EnumTest.TATA.str = "newVal"; 
    System.out.println(EnumTest.TATA); 
    } 

TATA 2 
newVal 

これらの値は、oftenly自分自身を除いて、私は不変でなければなりません列挙型変数のための最終的なキーワードを使用して誰も見たことがない、インスタンス作成(TOTO("TOTO 1"))で初期化されますが、。それは質問のポイントではなく、ただ私がこれを知っている唯一の人かどうか疑問に思っています。


変更可能な列挙型を作成するためのユースケースがあれば教えてください。

また、私たちが列挙型でできることの限界を知りたい(良い練習かどうか)。 私はそれをテストしていませんが、おそらくenumにSpring Beanを注入することができますか? 少なくとも、各インスタンスに注釈を付けることができます(例:@Deprecated works is fine)。

+7

フィールドに 'final'を使うのは列挙型でよく使われます。 –

答えて

7

怠惰な初期化(最初に使用されたときにいくつかのフィールド値を計算するか、しばしばそれらがまったく使用されない場合は計算する)、または(レジストリなどの)「通常の」変更可能なシングルトンオブジェクトです。

しかし、ほとんどの場合、列挙型オブジェクトは不変であり、フィールドは最終的なものでなければなりません。

-3

私が知りたいのは、可変列挙型を作成するためのユースケースがあるかどうかです。

列挙型定数自体は可変ではなく、フィールドは可変です。

+1

それは彼が私がそれを理解したように意味するものです。 –

+0

はい、それは私が意味するところですが、一般的な使用法は不変のenumを作成することですが、誰も "final"を使用しません –

+0

これは 'public'フィールドまたはフィールドを変更するパブリックメソッドを持つ' enum' 。しかし、私はフィールドを「final」と宣言する必要があることに同意します。 –

6

ここで興味深い事実を指摘していますが、私が懸念している限り、変更可能な列挙型フィールドの用途はありません。この言語「機能」(「バグ」?)を使用することは、他の開発者を混乱させる可能性があるだけでなく、悪い考えです。

+3

私は、列挙型は一般的に不変であると想定されているため、変更可能な列挙型を作成すると誤用につながるという点で私は同意します。列挙型に関連した変更可能な値は、 'EnumMap'で最も役立つことをお勧めします。それは、私は "useecase"があまりにも強すぎると言っていると思います。列挙型は実際には一意的なパターン(インスタンスの固定数)の拡張を表し、それを念頭に置いて他のクラスと同様に使用することができます。私は、MOSTの開発者がIMMUTABLEと考えることに慣れているため、変更可能な列挙型がメンテナンスの問題につながる可能性があることを再度強調します。 –

+0

無神経であると仮定して神様に感謝します。一般に設定者はありません:) –

+0

@JohnB、あなたが変更可能なフィールドを持つ列挙型を使用している場合の良い例を考えると間違いなく他のどの型よりも優れています。別の答え。しかし、私の答えはまだあります。私が心配している限りでは、少なくとも普通のクラスではうまくいかないユースケースはありません。列挙型は実際には何かについては正しいですが、概念的には、ブール値(2つの可能な値の固定セットがあります)またはint(2^32-1の可能な値の固定セット) 。あなたは 'true'で可変フィールドを持つと想像できますか? –

3

Alex Dの回答とコメントに応じて、私は可能なユースケースを投稿するという彼の提案を受けています。重力などを計算できる惑星の古い標準列挙の例を見てみましょう。各惑星での人間のコロニーの数を維持したかったと想像してください。はい、あなたはEnumMapを使用することができますが、私はより多くの可変フィールドが必要と値ごとに別々のマップまたは直感的だろう列挙型に関連付けられた変更可能な値を保持するために、別のクラスのいずれかを持つことができた場合を見ることができました。

私は私のコメントで述べたように、一般的に私は、列挙型が通常であり、不変でなければなりませんが、私は何のユースケースが存在しないことを伝えることは強すぎると感じていると信じています。

1

enumに変更可能なフィールドの使用を禁止する理由はありません。 enumを使用して、その型の値が有限の(そして既知の)可能性のセットの1つに属することを述べる。これらの値が時間とともに進化する性質を持つことができないことを意味するものではありません。

一部は、このようなシナリオのためのユースケースを求めています。 1つの例は、ErrorCategoryのようなenumタイプを使用することであり、エラーを予め定義された任意の数のカテゴリ(例えば、DocumentationError,SemanticErrorLayoutError ...)のうちの1つに分類する。

ErrorCategoriesが、requiresInstantInterventionまたはshouldFailBuildなどのプロパティを持っているとします。私はこれらのプロパティの値が時間の経過とともに変化する可能性があること、またはユーザーが設定できることを想像することができます。

実際にこれを実装する方法はたくさんありますが(上記のように実際にはEnumMapsなど)、スタイルについては常に論じることができますが、私にとってはenumの使用自体は間違いではありません。 enumはjavaの参照型であるため、==の動作は、最初に変更可能なプロパティがない場合と同じままです。

0

enumインスタンスは、enumクラスのpublic static finalフィールドです。したがって、変更可能な場合は、別のスレッドでその状態を変更することができます。これはあなたが望むものではないかもしれませんし、あなたがこれを理解していなければ問題を引き起こすかもしれません。