検索

キーワード


【Java】定数をまとめてグループ化⁉可読性向上『列挙型(Enum)』の解説‼

  • 公開日:2020-09-12 01:10:46
  • 最終更新日:2021-01-25 11:03:46
【Java】定数をまとめてグループ化⁉可読性向上『列挙型(Enum)』の解説‼

こんにちは。新人エンジニアのサトウです。

システムエンジニアとして駆け出したばかりですが、

初心者なりの視点でわかりやすい記事を心がけていますので参考になればうれしいです。


プログラム初心者✅にも、プログラムに興味がある人✨も、

短い時間で簡単にできますのでぜひこの記事を読んで試してみてください!

列挙(Enumeration)

列挙型(Enum型)

複数の定数をひとつにまとめてグループ化することができる型です。

列挙型で定義された値のことを列挙子と呼びます。


Javaにおいて列挙型はクラスです。java.lang.Enumクラスが継承されています。

クラスには勿論フィールドや定義した値を操作することができるメソッドが実装されています。

列挙型はプリミティブ型やクラスと同じように型として扱えますので、

変数の宣言や代入、制御構文での論理式、

メソッドへの引数や戻り値としても使用することができます。


一般的なクラスと異なる大きな点は、新しいインスタンス生成が外部からできないことです。

列挙型で定義された列挙子はプログラムの中で1つしかない「定数」として扱われます。

列挙型は上手く利用すればプログラムの保守性や可読性の向上につながる便利な機能です。


関連記事リンク:【Java】変数、定数の宣言と変数の列挙型、代入、型変換、型推論の使い方


列挙型(Enum型)の宣言

アクセス修飾子 enum 列挙名 {列挙子,列挙子2...};

列挙子はすべて大文字で宣言し、単語間の区切りを『_』(アンダースコア)で表すのが一般的です。

例:COLOR_RED, COLOR_BLUE等 


宣言のサンプルコードを確認しましょう。

public class Test {

	//列挙型(Enum型)の宣言
	protected enum Color {
		COLOR_PINK,
		COLOR_LIGHT_BLUE,
		COLOR_INDIGO,
		COLOR_YELLOW
	};
}

これで列挙型(Enum型)の宣言と列挙子を格納することができました。


関連記事リンク;【Java】 アクセス修飾子について紹介

列挙型の使用方法

型の宣言が出来たら定義した値(列挙子)を操作しましょう。

列挙子は以下のような構文で使用することができます。

列挙名.列挙子名
ex)Color.COLOR_PINK


宣言のサンプルコードに追記して実装してみます。

public class Test {

	//列挙型(Enum型)の宣言
	protected enum Color {
		COLOR_PINK,
		COLOR_LIGHT_BLUE,
		COLOR_INDIGO,
		COLOR_YELLOW
	};

	//列挙子の操作
	public static void main(String[] args) {

		System.out.println(Color.COLOR_PINK);
	}
}

出力結果

COLOR_PINK


フィールド/メソッド/コンストラクタの定義の仕方

列挙型はEnumクラスを継承しているので、フィールドやメソッド、コンストラクタを定義することができます。

フィールドとコンストラクタを定義することで列挙子へ独自を値を持たせることが可能になります。

またメソッドを使用し列挙子を操作することができます。


関連記事リンク:【Java】 メソッドについて紹介!/【Java】 コンストラクタの紹介!

列挙子への値の付与

フィールドとコンストラクタを定義することで列挙子へ独自の値を付与することが可能になります。

これにより、数値や別の識別子で列挙子を管理することができるメリットがあります。


値を付与した列挙子の書き方は以下のようになります。

列挙名.列挙子名(値)
ex)Color.COLOR_PINK(1)
   Color.COLOR_PINK("桃色"

列挙子の後に値を「( )」で囲み付与します。数値や文字列を値として付与することが可能です。


列挙子へ付与された値は以下のような構文で使用することができます。

列挙名.列挙子名.値のフィールド名
ex)Color.COLOR_PINK.level


サンプルコードで確認しましょう。

public class Test {

	//列挙型(Enum型)の宣言
	protected enum Color {
		COLOR_PINK(128),
		COLOR_LIGHT_BLUE(100),
		COLOR_INDIGO(50),
		COLOR_YELLOW(0);

		// フィールドの定義
		private final int level;

		// コンストラクタの定義
		private Color(int level) {
	        this.level = level;
		}
	}
	
	//列挙子の操作
	public static void main(String[] args) {
		System.out.println(Color.COLOR_PINK.level);
	}
}

出力結果

128

文字列(String型)でも同様に実装することができます。

コンストラクタのアクセス修飾子はprivateのみ使用可能となっています。

フィールド定義の修飾子finalはTestクラス内からの操作を防いでいます。

コンストラクタを記述しない場合、エラーが発生しますので注意しましょう。


関連記事リンク:【Java】final 修飾子について紹介!/【Java】 アクセス修飾子について紹介

int型とString型の両方の値付与

二つの値を同時に付与することも可能です。サンプルコードで確認しましょう。

public class Test {

	//列挙型(Enum型)の宣言
	protected enum Color {
		COLOR_PINK("桃色",128),
		COLOR_LIGHT_BLUE("水色",100),
		COLOR_INDIGO("紺色",50),
		COLOR_YELLOW("黄色",0);

		// フィールドの定義
		private final String japanese;
		private final int level;

		// コンストラクタの定義
		private Color(String japanese,int level) {
	        this.level = level;
	        this.japanese=japanese;
		}
	}

	//列挙子の操作
	public static void main(String[] args) {
		System.out.println(Color.COLOR_PINK);
		System.out.println(Color.COLOR_PINK.japanese);
		System.out.println(Color.COLOR_PINK.level);
	}
}

出力結果

COLOR_PINK
桃色
128


メソッドの紹介

Enumクラスにはいくつかのメソッドが実装されています。

Enum型の配下にメソッドを定義して列挙子を操作できます。ここでは基本的な5つのメソッドを紹介します。


String	name()

Enum定数(列挙子)の名前を取得します。オーバーライドができないのがtoStringメソッドと異なる点です。

参照:javadoc-Enum

int ordinal()

列挙子の順序を取得します。順序は0始め。

String	toString()

Enum定数(列挙子)の名前を取得します。

通常はnameメソッドと同じ結果を返しますが、オーバーライドする事で実装者が振る舞いを決めることができます。

public static 列挙型 valueOf(String 列挙子名)

指定された文字列と一致するEnum型の列挙子を取得します。

nullを指定した場合、IllegalArgumentException例外が発生します。

public static 列挙型配列 values()

対象の列挙型のすべての列挙子を取得します。



サンプルコードで確認しましょう。

import java.util.Arrays;

public class Test {

	//列挙型(Enum型)の宣言
	protected enum Color {
		COLOR_PINK,
		COLOR_LIGHT_BLUE,
		COLOR_INDIGO,
		COLOR_YELLOW;

		@Override
		public String toString() {
		  return "<" + name() + ">";
		}
	}

	//列挙子の操作
	public static void main(String[] args) {

		//nameメソッド
		System.out.println(Color.COLOR_PINK.name());

		//ordinalメソッド
		System.out.println(Color.COLOR_LIGHT_BLUE.ordinal());

		//toStringメソッド
		System.out.println(Color.COLOR_INDIGO.toString());

		//valueOfメソッド
		System.out.println(Color.valueOf("COLOR_YELLOW"));

		//valuesメソッド
		Color[] list=Color.values();
		System.out.println(Arrays.toString(list));

	}
}

出力結果

COLOR_PINK
1
<COLOR_INDIGO>
<COLOR_YELLOW>
[<COLOR_PINK>, <COLOR_LIGHT_BLUE>, <COLOR_INDIGO>, <COLOR_YELLOW>]

※valueOfメソッドとvaluesメソッドは出力した際に内部でtoStringメソッドを呼んでいます。


列挙子を利用した条件分岐の操作

Enumクラスにメソッドが実装されているおかげで、

列挙子を条件分岐などの操作で使用することが可能になっています。

if文の分岐処理

列挙子と文字列の比較を条件にして処理を分けます。

『Color.COLOR_PINK=="COLOR_PINK"』のようにそのままの値に==演算子を使用すると

if文の処理が正しく行えずエラーが発生してしまいますが、

メソッドを以下の様に使用することで条件分岐が可能になります。


toStringメソッドを使った条件(Stringの比較はequalsメソッドを使いましょう。)

※サンプルコードでは可読性を考慮して定数lbに格納しています。

Color.COLOR_LIGHT_BLUE.toString().equals("COLOR_LIGHT_BLUE")

valueOfメソッドを使った条件

Color.COLOR_PINK == Color.valueOf("COLOR_PINK")


サンプルコードを確認しましょう。

public class Test {

	//列挙型(Enum型)の宣言
	protected enum Color {
		COLOR_PINK,
		COLOR_LIGHT_BLUE,
		COLOR_INDIGO,
		COLOR_YELLOW;
	}

	//列挙子の操作
	public static void main(String[] args) {

		final String lb= Color.COLOR_LIGHT_BLUE.toString();
		if (lb.equals("COLOR_LIGHT_BLUE")) {
			System.out.println("列挙子と文字列の一致");
		}else{
			System.out.println("列挙子と文字列の不一致");
		}

		if (Color.COLOR_INDIGO == Color.valueOf("COLOR_YELLOW")) {
			System.out.println("列挙子と文字列の一致");
		}else{
			System.out.println("列挙子と文字列の不一致");
		}
	}
}

出力結果

列挙子と文字列の一致
列挙子と文字列の不一致


switch文の分岐処理

Java7以降の環境ではswitch文でString型を指定できるようになりましたが、

列挙型の列挙子でもString値と同じようにSwitch文で値を指定することができます。

分岐が多くなったときはif文の代わりにswitch-case文を使うと、可読性が高い実装ができます。


以下のような記述でcaseに列挙子をセットすることができます。Enum型名は必要ありません。

case COLOR_PINK:


サンプルコードを確認しましょう。

public class Test {

	//列挙型(Enum型)の宣言
	protected enum Color {
		COLOR_PINK,
		COLOR_LIGHT_BLUE,
		COLOR_INDIGO,
		COLOR_YELLOW;
	}



	//列挙子の操作
	public static void main(String[] args) {

		Color c = Color.COLOR_PINK;

		switch (c) {
		case COLOR_PINK:
		case COLOR_YELLOW:
			System.out.println("暖色");
			break;
		case COLOR_LIGHT_BLUE:
		case COLOR_INDIGO:
			System.out.println("寒色");
			break;
		default:
			System.out.println("無色");
			break;
		}
	}
}

出力結果

暖色



【補足】列挙型と定数(final修飾子を使って宣言された変数)の使い分け

列挙型で定義された列挙子はプログラムの中で1つしかない「定数」として扱われます。

一方で、final修飾子を使って宣言された変数も定数として扱うことができます。

◆列挙型

public class Test {
	//列挙型(Enum型)の宣言
	protected enum Color {
		COLOR_PINK,
		COLOR_LIGHT_BLUE,
		COLOR_INDIGO,
		COLOR_YELLOW;
	}
}

◆定数(final修飾子を使って宣言された変数)

public class Test {
	//定数の宣言
	public static final int COLOR_PINK = 0x0001;
	public static final int COLOR_LIGHT_BLUE = 0x0002;
	public static final int COLOR_INDIGO = 0x0003;
	public static final int COLOR_YELLOW = 0x0004;
}


列挙型を拡張して独自の値を持たせるなどしない場合は同じような使い方ができるので

どちらを使う方が良いのかを迷う時があると思います。

判断基準の一つとして、両者の特徴の違いを意識して使用選択することをお勧めします。


列挙型

決められた値以外は取り扱えないため、定数の種類・数が明確である。

また複数人が関わるプログラムでは認識の疎通を図れる。

定数そのものに意味がある場合の使用を推薦


定数

取り得る値・種類が豊富であるため、表現できる範囲が広い。

値そのものに意味がある場合の使用を推薦



これらを上手く利用してプログラムの保守性や可読性の向上につながることを願っています!


関連記事リンク:【Java】変数、定数の宣言と変数の列挙型、代入、型変換、型推論の使い方

        【Java】final 修飾子について紹介!/【Java】 アクセス修飾子について紹介


【著者】

新人IT勉強家SATO

読者を始め私自身も知りたい!と思うような知って得するプログラミング知識やIT情報を日々発信しております。
憧れの人物はコリン・ファース、渡部篤郎さん、仮面ライダー(子供のころから)
かような方々に負けない大人で在れる様、プログラミングを始め興味関心を持ったことを毎日勉強中デス !!

よく読まれている記事
【Java】JSPでタグライブラリを使う(JSTL)

【Java】JSPでタグライブラリを使う(JSTL)

こんにちは。エンジニアの新田です!ここでは、システムエンジニアとして働いている私が、システム開発手法や開発言語について紹介していこうと思います。今回は、JSPの標準タグライブラリ「JSTL」について紹介します。Javaについて勉強している方、Webアプリケーションを構築したいと思っている方の参考になれば幸いです!関連記事リンク: 【Java】JSPの基本的な構文/【Java】JSPのアクションタグ

【Java】Stringクラス文字列を操作するメソッドの使い方まとめ!実例も紹介!

【Java】Stringクラス文字列を操作するメソッドの使い方まとめ!実例も紹介!

こんにちは。新人エンジニアのサトウです。システムエンジニアとして駆け出したばかりですが、初心者なりの視点でわかりやすい記事を心がけていますので参考になればうれしいです。プログラム初心者✅にも、プログラムに興味がある人✨も、短い時間で簡単にできますのでぜひこの記事を読んで試してみてください!そもそもStringとは何?『 String 』... Java言語において文字列のデータ型を指します。基本デ

【Java】文字列の置き換え(String#format)!エスケープシーケンスのまとめも!!

【Java】文字列の置き換え(String#format)!エスケープシーケンスのまとめも!!

こんにちは。新人エンジニアのサトウです。システムエンジニアとして駆け出したばかりですが、初心者なりの視点でわかりやすい記事を心がけていますので参考になればうれしいです。プログラム初心者✅にも、プログラムに興味がある人✨も、短い時間で簡単にできますのでぜひこの記事を読んで試してみてください!Stringクラスformatメソッドの文字列整形【java.utilパッケージ】Formatterクラスfo

【Java】文字列格納後に変更可能!?StringBufferクラスとStringBuilderクラス!

【Java】文字列格納後に変更可能!?StringBufferクラスとStringBuilderクラス!

こんにちは。新人エンジニアのサトウです。システムエンジニアとして駆け出したばかりですが、初心者なりの視点でわかりやすい記事を心がけていますので参考になればうれしいです。プログラム初心者にも✅、プログラムに興味がある人✨も、短い時間で簡単にできますのでぜひこの記事を読んで試してみてください!文字列を扱う3つのクラス【java.langパッケージ】java.langパッケージの文字列を扱うクラスにはS

【Java】値?変数?型??しっかり解説!『データ型(プリミティブ型と参照型)』

【Java】値?変数?型??しっかり解説!『データ型(プリミティブ型と参照型)』

こんにちは。新人エンジニアのサトウです。システムエンジニアとして駆け出したばかりですが、初心者なりの視点でわかりやすい記事を心がけていますので参考になればうれしいです。プログラム初心者✅にも、プログラムに興味がある人✨も、短い時間で簡単にできますのでぜひこの記事を読んで試してみてください!プリミティブ型と参照型プログラム開発では型を持った変数を使ってデータのやり取りをしますが、データ型によって仕様