ホームページ  >  記事  >  Java  >  なぜ Java は列挙型を使用するのでしょうか?

なぜ Java は列挙型を使用するのでしょうか?

藏色散人
藏色散人オリジナル
2019-05-22 11:24:284440ブラウズ

最近、会社のコードで int 列挙を使用する方法がたくさんあることを発見しました。また、列挙に enum を使用する方法もいくつか見ました。これについて非常に興味があり、調査を行った後、enum を使用する必要がある理由をまとめるためにこの記事を書きました。

なぜ Java は列挙型を使用するのでしょうか?

#Java で列挙型を使用する必要があるのはなぜですか?

予約注文と非予約注文の 2 つの注文タイプがあるとします。

要件 1: submitOrder メソッドは、さまざまな注文タイプに応じてさまざまな処理を実行します。

要件 2: 注文タイプをオブジェクト OrderResult に設定します。

以下は 2 つの列挙メソッドを使用して実装されます。

int 列挙型

class IntEnumExample{
private static final PRE_ORDER = 1;
private static final NOT_PRE_ORDER = 2;
public void submitOrder(int orderType, OrderResult orderResult){
    orderResult.setType(orderType);
    if(orderType == PRE_ORDER){
        do something to process preOrder
    }else if(orderType == NOT_PRE_ORDER){
        do something to process other order
    }
}
public static void main(String [] args){
    IntEnumExample example = new IntEnumExample();
    //passing wrong type to the method, however, no compile error and runtime exception here, the bug is hard to be discerned.
    example.submitOrder(3, orderResult);
}
}

上の例からわかるように、int 列挙型の使用にはいくつかの欠点があります。 int 列挙型は型チェックを実行しません。

2 上の submitOrder メソッドには任意の int 値を渡すことができます。コードの可読性は低いです。ドキュメントやソース コードがないとわかりません。 submitOrder に渡される値の意味。

それだけでなく、以前プロジェクトのソナー スキャン コードを変更したときに見つかった問題と同様に、上の例のように int 列挙を使用するときに、多くの人が int 値を static Final として定義しませんでした。変数を Final として定義することを忘れた場合、int 列挙の値は変更される可能性がありますが、変数を static として定義することを忘れた場合、使用時に int 値が初期化されていない可能性があります。

つまり、バグの原因となります。

enum を使用して同じことを行う方法を見てみましょう。

class IntEnumExample{
 private enum ORDER_TYPE {
        NOT_PRE_ORDER(1),PRE_ORDER(2);
        private final int value;
        private ORDER_TYPE(int value){
            this.value = value;
        }
    }
public void submitOrder(ORDER_TYPE orderType, OrderResult orderResult){
    orderResult.setType(orderType);
    if(orderType == ORDER_TYPE.PRE_ORDER){
        do something to process preOrder
    }else if(orderType == ORDER_TYPE.NOT_PRE_ORDER){
        do something to process other order
    }
}
public static void main(String [] args){
    IntEnumExample example = new IntEnumExample();
    //compiler will complain error here, if argument is not the type in the enum.
    example.submitOrder(ORDER_TYPE.PRE_ORDER, orderResult);
}
}
上記のコードからわかるように、enum は前の例の問題をエレガントに解決します。

1. コンパイラは enum に対して型チェックを実行します。型が一致しない場合、コンパイラは直接エラーを報告します。

2. int 列挙型から直接 int 値を渡す方法と比較して、enum が列挙型オブジェクトを渡す方法はコードが読みやすく、渡された列挙型が一目瞭然です。

3. enum 型自体のオブジェクトは静的 Final です。

重要なヒント:

各列挙型に int 値を割り当てたい場合は、上記の定義例では enum を使用する必要があることにも言及する価値があります。方法。

private enum ORDER_TYPE {
       NOT_PRE_ORDER(1),PRE_ORDER(2);
       private final int value;
       private ORDER_TYPE(int value){
           this.value = value;
       }
   }

列挙型の性質もクラスであるため、メソッド ORDER_TYPE(int value) はこの列挙型のコンストラクターです。したがって、各列挙型は、初期化中に対応する値をコンストラクターに渡す必要があります。例: PRE_ORDER(2)。

この場合、列挙型に対応する int 値を取得したい場合は、ORDER_TYPE.PRE_ORDER.value を通じて取得できます。

enum の使用法については別途説明します。これは、enum の ordinal() メソッドを直接使用して、enum 型と int 型の関連付けを直接実現する人もいるからです。 ordinal() メソッドは、列挙型が定義されたときの序数を返します。たとえば、ORDER_TYPE.PRE_ORDER.value.ordinal() は値 0 を返します。したがって、列挙型に対応する int 値の取得も、ORDER_TYPE.PRE_ORDER.value.ordinal() 1 によって実現できるようです。

ordinal() メソッドは使用しないでください。 ordinal() メソッドは使用しないでください。 ordinal() メソッドは使用しないでください。大事なことは3回言うのに、なぜ?

序数は非常に信頼性が低く、変更される可能性があります。ある日、ORDER_TYPE の定義が変更され、いくつかの型を追加する必要があるか、次のように NOT_PRE_ORDER と PRE_ORDER の順序が誤って変更されたとします。

private enum ORDER_TYPE {
       PRE_ORDER,NOT_PRE_ORDER;
   }

これにより、発見が困難な重大なバグが発生しますが、コンパイル時や実行時にエラーは発生しません。

したがって、 ordianl() メソッドに依存しないでください。

関連する学習の推奨事項:

Java 基本チュートリアル

以上がなぜ Java は列挙型を使用するのでしょうか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。