2009-09-14 11 views
10

Javaの列挙型とは何ですか?どのように機能するのですか?どこで私はそれらを使用することができますか?
アプリで列挙型を使用せずに行うことはできますか、それを無視するよりも使いやすいほど強力ですか?Javaで列挙型を理解する

答えて

40

Java 5+の列挙型は、基本的にインスタンスの事前定義されたセットを持つクラスです。それらは、例えば、整数定数の集合を置き換えることを意図している。それらは型安全性を強制することができるので、定数にすることが好ましい。

ので、代わりの:

あなたが持っている
public class Suit { 
    public final static int SPADES = 1; 
    public final static int CLUBS = 2 
    public final static int HEARTS = 3; 
    public final static int DIAMONDS = 4; 
} 

public enum Suit { 
    SPADES, CLUBS, HEARTS, DIAMONDS 
} 

利点は以下のとおりです。

  1. 型の安全性。関数の引数、戻り値の型、クラスメンバまたはローカル変数を特定のEnum型に宣言することができ、コンパイラは型の安全性を強制します。
  2. 列挙型は基本的にクラスです。彼らはインターフェースを実装したり、行動を取ることができます。

    int i = Suit.DIAMONDS * Suit.CLUBS; 
    

    か、スーツを期待して関数に11を渡すことができます:最初の例では、これらが有効なステートメントですので

型の安全性が問題です。あなたは型保証された列挙型でこれを行うことはできません。

あなたは型の安全性を提供するために、スーツのクラスを使用することができますし、Java 5ジョシュ・ブロッホ(あるEffective Javaでは、私見Javaプログラマのためのを読まなければならない)の前に、これは解決したとなったタイプセーフな列挙型のパターンを推進しましたJava 5+列挙型これにはかなりの量の定型文があり、コンシューマを呼び出さないシリアル化やreadResolve()メソッドをオーバーライドしなければならないインスタンスが1つしかないなど、人が気にしないコーナーケースもあります。例えば

public enum CardColour { 
    RED, BLACK 
} 

public enum Suit { 
    SPADES(CardColour.BLACK), 
    CLUBS(CardColour.BLACK), 
    HEARTS(CardColour.RED), 
    DIAMONDS(CardColour.RED); 

    private final CardColour colour; 

    Suit(CardColour colour) { this.colour = colour; } 

    public CardColour getColour() { return colour; } 
} 

編集:日はintroduction to typesafe enumsています。

インターフェイスに関しては、実際には代わりにenumを補完します。あなたはそのスーツはインタフェースであり、あなたはこの必要があるだろうと言うことができるように:

public interface Suit { 
    CardColour getColour(); 
} 

問題は、あなたが行くと定義する300種類のスーツを、あなたはまた、スペード、数回を定義することができます可能性があることです。列挙型のもう1つの利点は、各列挙型の値が1つしかないことです。特定の列挙型のインスタンスであるすべて、Bの

a.equals(b) == b.equals(a) == (a == b) 

を:一般的に、これは、この等式が成立する意味、カノニカル値を有すると呼ばれます。

if (card.getSuit().equals(Suit.SPADES)) { ... } 

あなたが書くことができます:

迅速かつ読み、一般的に容易である
if (card.getSuit() == Suit.SPADES) { ... } 

をこれが代わりに書いていることを意味します。 Plus IDEは、さまざまな型の列挙型を比較す​​る場合には、同等ではない可能性があり、有用で初期のエラーチェックの形式である可能性があると主張します。

+1

Sun's Guide(http://java.sun.com/j2se/1.5.0/docs/guide/language/enums.html)は、潜在的な可能性をよく示しています。私はさらに読むための参考資料を追加することをお勧めします。 –

+0

@cletus ...インタフェースを同じものに使用できませんでしたか? –

+0

@cletus:私はそれの "タイプセーフティ"の部分を理解していませんでした。 Javaクラスは型の安全性を提供しませんか? –

1

太陽のenum documentationがおそらく最も良い説明です。もちろん、JavaプログラマがJava 1.5がリリースされるまでは、Javaプログラマが確かにそうしていたのと同じように、それらなしで実行できます。通常は1.5より前のバージョンのJavaで定数を使用して同じことを達成します。しかし、列挙型はとても便利です。

+0

はなぜそれは、Java 1.5に含まれていましたか?それは強力ですか? –

1

状況が表示されない場合は、その必要はありません。

彼らはあなたが物質の状態を表現したい場合たとえば、あなたが持っている可能性があり、あなたは物事の明確に定義されたセットを持つことができる:

彼らはセットを表現するためにオブジェクトを使用しての古いスタイルを打つ
enum MatterState { 
    Solid, 
    Liquid, 
    Gas; 
} 

多くの方法で、いくつかは:

  • スイッチ ステートメントで使用できます。
  • 少ないコード。
  • 組み込み/文字列。
+0

あなたは正確な例を使って答えることに私を打ち負かしました;) – n002213f

+3

忘れてしまったプラズマ:p –

0

私の解釈では、列挙型は他のものより読みやすくしています。基本的に1-6のような値を[Happy、Sad、Angryなど]のようなわかりやすい名前に置き換えるのに使用されます期待している解決策を説明するために小さな変数セットを使用する必要があるときは、

public class MyEnum { 

    // Object instantiated at declaration 
    public static final MyEnum ONE = new MyEnum(); 
    public static final MyEnum TWO = new MyEnum(); 
    public static final MyEnum THREE = new MyEnum(); 

    // Notice a private constructor 
    // There is no way outside MyEnum class call it 
    private MyEnum() { ... } 


} 

を次のように列挙型の

+2

@bogerton:実際には、Java enumsを使うことに大きなタイプセーフの利点があります。 @ cletusの優れた答えを見てください。 –

11

だと思うだから列挙型としてMyEnumは

public enum MyEnum { 
    ONE, 
    TWO, 
    THREE; 
} 

の両方がにいくつかの追加情報を追加するには

に関して、

1

似ているだろうそれをもっと知るには、変数とその値のコンセプトから始めてください。私はあなたが今確信しているので、各変数は宣言された型(Javaプリミティブ型など)を持っています。各タイプには、それぞれに対応する値があります。たとえば、char型の変数は、すべての個々の文字をその値として受け入れることができます。したがって、変数を宣言したい場合は、すべての文字定数を受け入れることができます。たとえば、すべての文字定数はaCharToStopProgram変数の許容と意味がある:

char aCharToStopProgram = getUserInput(); 

しかし、あなたが制限された値を持っている場合については、私はあなたの変数の値のドメインが特殊な値に制限されているものを意味します。たとえば、システムの多肢選択式質問の価値を保持するuserChoiceがあります。だから、ちょうど「a」、「b」、「c」、「d」は意味があります。プログラムコードの他のセクション(または他の理由)にこの変数に 's'などの無意味な値が割り当てられないようにする必要はありません。次のように、文字定数を受け入れることができる変数にcharプリミティブ型を使用するのは当然です。

char userChoice = getUserChoice(); 

この場合、Javaは列挙型を提供します。これは、enumキーワードを使用して、名前付きの呼び出し(新しいオブジェクトを作成することはできません)という制限付き固定インスタンスを持つ新しいクラスを定義できることを意味します。たとえば、次のように

enum MultipleChoiceAnswer { A, B, C, D }; 

または

public enum MultipleChoiceAnswer { 

    A('a'), B('b'), C('c'), D('d'); 

    private char choice; 

    private MultipleChoiceAnswer(char choice) { 
     this.choice = choice; 
    } 

    public String getChoice() { 
     return choice; 
    } 
} 

あなたがあなた自身の型の変数を定義することができた結果として:

MultipleChoiceAnswer userChoice = getUserChoice();//OR MultipleChoiceAnswer.A