データ構造Javaデータ構造---列挙

列挙する

1.列挙の背景と定義

列挙型は、JDK1.5以降に導入されました。主な目的は、定数のセットを編成することです。それ以前は、定数のセットは通常、定数を定義する方法で表されていました。

    public static final int RED = 1;
    public static final int BLACK = 2;
    public static final int GREEN = 3;

ただし、定数の例には悪い点があります。たとえば、数値が1である場合でも、REDと誤解される可能性があります。これで、列挙型を直接使用して整理できるようになり、型、列挙型が作成されます。通常の成形の代わりに1。

	public enum TestEnum {
    
    
		RED,BLACK,GREEN;
	}

利点:統一された管理
シナリオの定数を整理します:エラーステータスコード、メッセージタイプ、色分割、ステートマシンなど...

本質:これはjava.lang.Enum、のサブクラスです。つまり、明示的な継承がない場合でも、Enumデフォルトでこのクラスを継承する、自分で作成した列挙型クラスです。

2.列挙型の使用

2.1switchステートメント

public enum TestEnum {
    
    
    RED,BLACK,GREEN,PINK;

    public static void main(String[] args) {
    
    
        TestEnum testEnum = TestEnum.BLACK;
        switch (testEnum) {
    
    
            case RED:
                System.out.println("red!");
                break;
            case BLACK:
                System.out.println("black!");
                break;
            case GREEN:
                System.out.println("green!");
                break;
            case PINK:
                System.out.println("pink!");
                break;
            default:
                break;
        }
    }
}

2.2一般的に使用される方法

Enumクラスの一般的なメソッド

メソッド名 説明
values() 列挙型のすべてのメンバーを配列として返します
ordinal() 列挙型メンバーのインデックス位置を取得します
valueOf() 通常の文字列を列挙型インスタンスに変換します
compareTo() 2つの列挙型メンバーが定義されている順序を比較します

2.2.1values()の使用

public enum TestEnum {
    
    
    RED,BLACK,GREEN,PINK;

    public static void main(String[] args) {
    
    
        TestEnum[] testEnums = TestEnum.values();
        for (int i = 0; i < testEnums.length; i++) {
    
    
            System.out.println(testEnums[i]);
        }
    }
}

ここに画像の説明を挿入

2.2.2 ordinal()の使用

public enum TestEnum {
    
    
    RED,BLACK,GREEN,PINK;

    public static void main(String[] args) {
    
    
        TestEnum[] testEnums = TestEnum.values();
        for (int i = 0; i < testEnums.length; i++) {
    
    
            System.out.println(testEnums[i].ordinal());
        }
    }
}

ここに画像の説明を挿入

2.2.3 valueOf()の使用

public enum TestEnum {
    
    
    RED,BLACK,GREEN,PINK;

    public static void main(String[] args) {
    
    
        System.out.println(TestEnum.valueOf("RED"));
        System.out.println(TestEnum.valueOf("BLACK"));
        System.out.println(TestEnum.valueOf("WHITE"));
    }
}

ここに画像の説明を挿入

2.2.4 compareTo()の使用

public enum TestEnum {
    
    
    RED,BLACK,GREEN,PINK;

    public static void main(String[] args) {
    
    
        TestEnum testEnum1 = TestEnum.RED;
        TestEnum testEnum2 = TestEnum.BLACK;
        System.out.println(testEnum1.compareTo(testEnum2));
        System.out.println(RED.compareTo(GREEN));
        System.out.println(PINK.compareTo(RED));
    }
}

ここに画像の説明を挿入

2.2.5コンストラクタ

public enum TestEnum {
    
    
    RED("red",1),BLACK("black",11),GREEN("green",111),PINK("pink",1111);

    private String name;
    private int ordinal;

    private TestEnum(String name,int ordinal){
    
    
        this.name = name;
        this.ordinal = ordinal;
    }

    public static TestEnum getEnumKey (int ordinal) {
    
    
        for (TestEnum t :TestEnum.values()){
    
    
            if(t.ordinal == ordinal){
    
    
                return t;
            }
        }
        return null;
    }

    public static void main(String[] args) {
    
    
        System.out.println(getEnumKey(1111));
    }
}

ここに画像の説明を挿入

2.3注意事項

  1. 自分で作成した列挙型クラスは、デフォルトで継承されますEnum
  2. 独自の列挙型クラスのコンストラクターはデフォルトでプライベート
  3. 値メソッドを含まないカスタム列挙型を作成し、Javaファイルをコンパイルすると、Javaコンパイラが自動的にこのメソッドの生成を支援します。

3.列挙の長所と短所

アドバンテージ:

  1. 列挙型定数はより単純で安全です。
  2. 列挙型には、より洗練されたコードのための組み込みメソッドがあります

欠点:

  1. 継承不可、拡張不可

4.列挙と反映

リフレクションで見たところ、コンストラクターがプライベートであっても、リフレクションを介してインスタンスオブジェクトを取得でき、列挙型のコンストラクターもプライベートであることがわかりました。取得できますか?次に、実験してみましょう。

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class Reflect {
    
    
    public static void reflectPrivateConstructor() {
    
    
        try {
    
    
            Class<?> c = Class.forName("TestEnum");
            Constructor<?> constructor = c.getDeclaredConstructor(String.class,int.class);

            constructor.setAccessible(true);

            TestEnum testEnum = (TestEnum) constructor.newInstance("1231123",123123);

            System.out.println(testEnum);
        } catch (ClassNotFoundException | NoSuchMethodException e) {
    
    
            e.printStackTrace();
        } catch (InvocationTargetException e) {
    
    
            e.printStackTrace();
        } catch (InstantiationException e) {
    
    
            e.printStackTrace();
        } catch (IllegalAccessException e) {
    
    
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
    
    
        reflectPrivateConstructor();
    }
}

実行後にエラーが報告されます。
ここに画像の説明を挿入
ここでの意味は、対応する構築メソッドがないことです。
なぜこれが発生するのですか?
デフォルトの継承java.lang.Enumは、コンストラクターを除く親クラスからすべてを継承し、サブクラスは親クラスの構築を支援する必要があるためです。私たちが作成したクラスは、親クラスの構築に役立ちませんでした。列挙は特別です。2つ作成しましたが、デフォルトで2つのパラメーターも追加しました。
ここに画像の説明を挿入
つまり、独自のコンストラクターには2つのパラメーターがあり、1つはStringで、もう1つはint。同時に、デフォルトで2つのパラメーターが背後にあります。1つはStringで、もう1つはintです。つまり、ここでは4つのパラメーターを正しく指定しています。

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class Reflect {
    
    
    public static void reflectPrivateConstructor() {
    
    
        try {
    
    
            Class<?> c = Class.forName("TestEnum");
            Constructor<?> constructor = c.getDeclaredConstructor(String.class,int.class,String.class,int.class);

            constructor.setAccessible(true);

            TestEnum testEnum = (TestEnum) constructor.newInstance("1231123",123123,"4444",2323);

            System.out.println(testEnum);
        } catch (ClassNotFoundException | NoSuchMethodException e) {
    
    
            e.printStackTrace();
        } catch (InvocationTargetException e) {
    
    
            e.printStackTrace();
        } catch (InstantiationException e) {
    
    
            e.printStackTrace();
        } catch (IllegalAccessException e) {
    
    
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
    
    
        reflectPrivateConstructor();
    }
}

実行後、
ここに画像の説明を挿入
この時点での異常情報は、それが私の方法の1つであることを示しています。この方法は次のとおりです。newInstance()エラーが報告されます。
ソースコードを表示します。
ここに画像の説明を挿入

4.1まとめ

リフレクションは強力ですが、列挙クラスのインスタンスはリフレクションでは取得できません。

おすすめ

転載: blog.csdn.net/wwzzzzzzzzzzzzz/article/details/123252492