5

先日、友人の Java を手伝っていたところ、Enum について尋ねられました。(何かのような)のC構文を説明しました

enumeration Difficulty{
    BEGINNER= 1;
    PRO=5;
    EXPERT = 11;
}

行くべき道ではありませんでした.Java構文はsomething(1);、intを受け入れるコンストラクタを作成し、これとあれを行いました...など。

しかし、彼らは私を止めて、「コンストラクターなどを使用している場合、列挙型にこだわるのはなぜですか? 新しいクラスを作成しないのはなぜですか?」と尋ねました。

と、答えられませんでした。では、なぜこの場合、クラスではなく列挙型を使用するのでしょうか?

4

7 に答える 7

10

列挙型は厳密に制限されています。指定された値以外の列挙値を定義することはできません (一方、クラスをnew使用すると、新しい値を作成するために呼び出すことができます)。

列挙型は、少なくともほとんどの JVM によって大幅に最適化されており、列挙型のコンパクトさと速度を利用する新しいクラスと言語機能もあります。たとえば、作成された新しいクラス と がEnumSetありEnumMap、これらはそれぞれビットセットと配列を使用して列挙型キー セットまたはマップを実装します (おそらく、これらの抽象データ型の最速の実装です)。

switchさらに、列挙型はステートメントで使用できます。Java1.7 より前の場合は、これがカスタマイズされたswitchステートメントの最良のオプションです (String型の安全性のために、値を使用するよりもおそらく優れています。列挙型の値を間違って入力すると、コンパイル時エラーが発生しますが、文字列を間違って入力すると、より陰湿な実行時エラー、またはさらに悪いことに、コードを実際に見つめてタイプミスを確認するまで理解できない論理エラー)。

于 2012-08-14T13:53:07.033 に答える
6

実際、Java の Enum は、クラス階層全体を宣言するための構文糖衣にすぎません。

書き込み:

public enum MyEnum {
   FOO, BAR
}

書くこととほぼ同じです

public abstract class MyEnum {
    public static final MyEnum FOO = new MyEnum(){};
    public static final MyEnum BAR = new MyEnum(){};

    private MyEnum(){}
}

最初はやり過ぎに思えるかもしれませんが、次のようなクラスで実行できるすべてのことを実行できることに気付きます。

public enum Operators {
    ADD("+"){ 
        public double apply(double lhs, double rhs){ return lhs + rhs; }
    },

    SUBTRACT("-"){ 
        public double apply(double lhs, double rhs){ return lhs - rhs; }
    },

    MULTIPLY("*"){ 
        public double apply(double lhs, double rhs){ return lhs * rhs; }
    },

    DIVIDE("/"){ 
        public double apply(double lhs, double rhs){ return lhs / rhs; }
    };

    private final String symbol;

    Operators(String symbol){
        this.symbol = symbol;
    }

    public abstract double apply(double lhs, double rhs);
}

これは次のものと同等になりました(さらにいくつかの便利なメソッドが追加されました):

public abstract class Operators {
    public static final Operators ADD = new Operators("+"){ 
        public double apply(double lhs, double rhs){ return lhs + rhs; }
    };

    public static final Operators SUBTRACT = new Operators("-"){ 
        public double apply(double lhs, double rhs){ return lhs - rhs; }
    };

    public static final Operators MULTIPLY = new Operators("*"){ 
        public double apply(double lhs, double rhs){ return lhs * rhs; }
    },

    public static final Operators DIVIDE = new Operators("/"){ 
        public double apply(double lhs, double rhs){ return lhs / rhs; }
    };

    private final String symbol;

    private Operators(String symbol){
        this.symbol = symbol;
    }

    public abstract double apply(double lhs, double rhs);
}

これは、非常に基本的な C バージョンよりもはるかに強力です。そしてもちろん、列挙型では、列挙型の各メンバーがシングルトンであることが保証されています。

于 2012-08-14T14:02:29.810 に答える
6

enum には、plains クラスにはない多くの機能があります。

  • それらには、1 か所で定義する固定数のインスタンスがあります。
  • これらは、switch ステートメントで使用できます。
  • 列挙型の完全なリストを取得する
  • 文字列から列挙型を検索します。
  • 列挙型の名前を取得できます。
  • 個々の列挙値をサブクラス化できます。
于 2012-08-14T13:54:26.050 に答える
4

列挙型を使用する理由は次のとおりです -

1) Enum はタイプ セーフであり、事前定義された enum 定数以外のものを enum 変数に割り当てることはできません。

2) Enum には独自の名前空間があります。

3) Enum の最も優れた機能は、int または char プリミティブ データ型のような Switch ステートメント内で Java で Enum を使用できることです。しかし、Java 7 では、switch ステートメントで String を使用できます。

4) Java の Enum に新しい定数を追加するのは簡単で、既存のコードを壊さずに新しい定数を追加できます。

于 2012-08-14T13:53:16.163 に答える
1

Enum は、Java の優れたシングルトンにもなります。

http://en.wikipedia.org/wiki/Singleton_pattern#The_Enum_way

これは、クラスの代わりに列挙型を使用できるもう 1 つのケースだと思います。

于 2012-08-20T16:08:06.423 に答える
0

... ehhm ... enum :)で列挙された値の固定セットがある場合は、列挙型を使用します:)

クラスが記述する何かのインスタンスがいくつでも必要な場合は、クラスを使用します。

于 2012-08-14T13:52:34.617 に答える
0

クラスは任意の数のインスタンスを持つことができるのに対し、「列挙型」では、インスタンスの数は列挙自体の要素に制限されているため (コンストラクターをプライベートにする必要があるのはそのためです)、これらのインスタンスには静的にアクセスできます。

于 2012-08-14T13:53:41.137 に答える