【Java】 列挙型について

に公開

Java Goldを取得しようと最近学習をしております。
学んだことをアウトプットしていきたいと思いこの場で行おうと思います!
少しでも参考になれば幸いです。なにか間違い等あれば優しく指摘をしてくれますと嬉しいです😁

列挙型

列挙型と言う名のクラスに値を保持するためのものだと思っています。
例えば、「信号」という別のクラスファイルが有りそこで「赤・黄・青」という値を使う場面がありその他のクラスファイルでは「ステータスの管理」をするものがありそこでは色で「未実行・実行中・完了」としています。
そんなときにすでに定義されている3色の値があればそれを呼び出すだけでよくなるのでとても便利ですよね?
それを提供するのが列挙型になります。

列挙型が定義できる場所

  • 定義されたクラスの中
  • 列挙型のみが定義されているソースファイル

列挙型の実行時の挙動

列挙型は、java.lang.Enumクラスを継承したfinalクラス
また、指定した値はpublic static finalを指定される
そのため、後述べでも記載するけれどダブルクオーテーションで囲う必要がない

列挙型の定義

【修飾子】enum 列挙型名 {値1, 値2, 値3};

定義にはenumを指定します。
また、値は""(ダブルクオーテーション)で囲まないです。

実行時の動き

例:enum Color {RED, BLUE, GREEN}

enum -> 列挙型の定義に必要
Color -> public static final Color extend (java.lang.Enum)<Color>{}
{RED, BLUE, GREEN} ->

public static final Color RED;
public static final Color BLUE;
public static final Color GREEN;

また、コンパイル時自動的に以下の2つのメソッドが追加されます

  • values()
  • valueOf()

values() -> 列挙型の値を配列で返す
valueOf() -> 引数の名前の値を返す

上記の説明を見てもらえばわかるのですが、コンパイルすると値はstatic変数となります
つまり列挙型とは実体を持つクラスということになります。

実際の呼び出し

列挙型名.クラス変数
上記の例でいうとColor.RED;になります

コンストラクタ / メソッド / メンバ変数の追加

通常のクラスのようにコンストラクタ・メソッド・メンバ変数の記述は可能です
この場合はSTD04には引数を持たせないでカラにしました。
getMaterial()メソッドで呼び出す際に、引数のあるものはそれが出力され、空の場合は「日本語」が初期値としてなるようにしています。

メソッドは別ファイルで実行する際はstaticを指定しないと読み込みができないので注意が必要です。

est03_01.java

enum est03_01 {
    STD01("Japaneses"),
    STD02("English"),
    STD03("Spanish"),
    STD04();

    // メンバ変数
    final String material;

    // コンストラクタ
    est03_01() {
        this.material = "日本語";
    }
    est03_01(String material) {
        this.material = material;
    }

    // メソッド
	public static String getMaterial() {
    	return est03_01.STD04.material; // コンストラクタの確認用
	}
	public static String showData() {
    	return Arrays.toString(est03_01.values()); // 配列の要素すべて取得
	}
	public static String getValue() {
    	return String.valueOf(STD01); // 列挙型の値を一つ取得
	}


}

main.java

class Main {
	public static void main(String[] args) {
		System.out.println("コンストラクタ:" + est03_01.STD04);
		System.out.println("test01:" + est03_01.STD01);
		System.out.println("test02:" + est03_01.showData());
		System.out.println("列挙型の値をひとつ:" + est03_01.getValue());
	}
}

出力結果

コンストラクタ:日本語
test01: STD01
test02: [STD01, STD02, STD03]
列挙型の値をひとつ:STD01

列挙型の中身の確認方法

この例はmain.javaにて記載していることが前提の例です。
System.out.println(Color.values());だけで中身を見ようとするとオブジェクトとして返ってくるので「[Lchapter01.std03$1Color;@8efb846」のように帰ってきて実際の中身は確認できません。
そこでArrays.toStringをつけることで無事に配列として確認ができます

enum Color {
	BLUE,
	RED,
	GREEN
} 
System.out.println(Arrays.toString(Color.values());
//出力結果:[BLUE, RED, GREEN]

個別での呼び出し

enum Color {
	BLUE,
	RED,
	GREEN
} 
System.out.println(Color.valueOf(RED));
//出力結果:RED

列挙型のまとめ

  • 「enum」で宣言
  • コンパイルするとクラスファイルが生成される
  • 呼び出しは「列挙型名.クラス変数」
  • 生成されるクラスはfinalが指定されているためextendsでの継承はできない
  • 抽象メソッドの使用・インターフェースの実装は可能
  • コンストラクタ・メソッド・メンバ変数の記載も可能
  • 順は列記の順序となる
  • newキーワードでのインスタンス化はできない

Discussion