Javaの定数Enumの使い方とは?基本の使い方3つとメリット5つ

- SE
- JavaのEnumとはどういうときに使うのでしょうか。
- PM
- オブジェクトを宣言したり、名称の定義ができたり、Enum同士を比較したりするときに定数Enumを使います。
この記事でわかること
Javaとは?
Javaとはクラスベースのオブジェクト指向のプログラミング言語です。元々はサン・マイクロシステムズという企業で開発・運用されていましたが、後にOracleに買収されました。
近年ではJavaScriptやPythonといったプログラミング言語の人気が上昇していますが、それでもノートPCや携帯電話(スマホ)、科学計算用スーパーコンピュータなど多くのデバイスで利用され続けています。
特に近年ではスマホアプリや、勘定系の業務アプリケーションの構築で使用されています。今回はこのJavaにおける定数クラスEnumの使い方を紹介します。
Enumとは?
今まで定数を宣言するのには数値型が用いられてきました。しかし数値型の定数には管理が煩雑になったり、同じ1という値に違う意味が混在したりといったデメリットがありました。
こういったデメリットを解消できるのがEnumです。Javaではバージョン5からEnumが使用できます(現在の最新バージョンは14)。
JavaのEnumはクラスとして宣言します。使い方は後述しますがclass識別子ではなくenum識別子を用います。Enumクラスには任意のメソッドやフィールドを追加したり、任意のインタフェースを実装したりできます。
ちなみにEnum.classはjava.langパッケージに属しており
1 2 3 4 |
public abstract class Enum<E extends Enum<E>> implements Constable, Comparable<E>, Serializable |
と定義されています。
Enumの基本的な使い方3つ
Enumの基本的な使い方である「オブジェクトを宣言する」「名称の定義ができる」「Enum同士を比較する」を順に説明していきます。実際のソースコードも載せているので合わせてご確認ください。
使い方1:オブジェクトを宣言する
Javaでの使い方は、オブジェクトの宣言は通常のクラス宣言をするようにEnum識別子で宣言します(class識別子は使用しません)。ここではCardというEnumを宣言しています。
1 2 3 4 |
public enum Card { } |
使い方2:名称の定義ができる
名称の定義はJavaのクラス名と同様に任意の名称をつけることができます。定数というと、intといった数値型が基本となりますが、Enumはそれに縛られません。ここではカードのEnumとしてHEART, DIAMOND, SPADE, CLUBという名称で定義します。
1 2 3 4 5 |
public enum Card { HEART, DIAMOND, SPADE, CLUB; } |
使い方3:Enum同士を比較する
JavaでのEnum同士を比較する使い方を以下のif文とswitch文で紹介します。それぞれ実際のソースコードで使い方を見てください。いずれもintやStringのように扱うことができます。
if文
Javaでのif文を使ったEnum同士の比較は以下のようになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
public class TrumpGame { public static void main(String[] args) { Card diamond1 = Card.DIAMOND; Card diamond2 = Card.DIAMOND; Card spade1 = Card.SPADE; if(diamond1.equals(diamond2)) { System.out.println("同じCard(DIAMOND)です。"); }else { System.out.println("異なるCardです。"); } if(diamond1.equals(spade1)) { System.out.println("同じCard(DIAMOND)です。"); }else { System.out.println("異なるCardです。"); } } } |
switch文
Javaでの>switch文を使ったEnum同士の比較は以下のようになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
public class TrumpGame { public static void main(String[] args) { Card diamond1 = Card.DIAMOND; switch(diamond1) { case DIAMOND: System.out.println("DIAMONDです"); break; case CLUB: System.out.println("CLUBです"); break; case HEART: System.out.println("HEARTです"); break; case SPADE: System.out.println("SPADEです"); break; } } } |
Enumの2つのメソッドの使い方
Enumクラスが持つ2つのメソッドの使い方について説明します。valuesメソッドとvalueOfメソッドです。
この2つのメソッドはEnum定数では必ず付与されます。
メソッド1:values
valuesは定義したEnumをすべて返すメソッドです。
1 2 3 4 5 |
for (Card type : Card.values()) { System.out.println(type); } |
上のコードのような使い方で以下の出力を得られます。
1 2 3 4 |
HEART DIAMOND SPADE CLUB |
メソッド2:valueOf
valueOfは指定された名前を持つ指定されたEnum型のEnum定数を返すメソッドです。
1 2 3 |
System.out.println(Card.valueOf("DIAMOND")); |
上のコードのような使い方で以下の出力を得られます。
1 |
DIAMOND |
Javaの定数Enumを使うメリット5つ
Javaの定数Enumにはメリットがいくつかあります。
その内5つの「1つの定数に複数定義できる」「複数の定数を1つの型で管理できる」「定数を管理しやすい」「安全性が高い」「出力情報に意味を持たせる」を紹介します。
メリット1:1つの定数に複数定義できる
今までの使い方で見てきたように、JavaではEnumを使うことで1つの定数に複数の定義をすることができます。CardというEnumの例ではHEART,DIAMOND,SPADE,CLUBを定義しました。
メリット2:複数の定数を1つの型で管理できる
JavaではEnumを使わない定数ではintなどの数値型が使われることが多いです。その場合、1つのクラスに全ての定数を定義したりと、管理が煩雑になります。Enumの使い方を適切に行えば定数を意味のあるまとまりごとに1つの型で管理することができます。
メリット3:定数を管理しやすい
メリット2でも紹介しましたが、JavaでのEnumでも意味のあるまとまりごとに管理できるため特定の項目に分けて管理することができます。前述してきた使い方をすることで値の重複定義なども事前に防ぐことができます。
メリット4:安全性が高い
EnumはJavaのclassのように宣言して取り扱います。これによりJavaのコンパイラによって異なるEnum(型)同士の比較は事前にエラーとして判別できるようになっています。
また IntelliJやNetBeansといったJavaのIDEAを使うことでコード補完の恩恵も受けることができます。このためint型などの定数と比べて安全性が高い開発をすることができます。
メリット5:出力情報に意味を持たせる
旧来のint型の定数では出力してもただの数値が表示されるだけです。このような使い方では「処理結果:1」と出力されてもその意味を知る人でなければ成功したのか失敗したのか読み取れません。
しかしEnumであれば定数に意味を持たせることができます。例えばSUCCESS、FAILといったように定義することができます。
- SE
- Enumにはいろいろなメリットがあるのですね。
- PM
- そうですね。JavaのEnumのメリットをよく理解してぜひ使ってみてください。
Javaの定数Enumを使ってみよう
Javaの定数Enumの使い方とそのメリットをご紹介しました。管理面や安全性のことなど、1人で開発する中では気にしない部分も多かったのではないでしょうか。
最後にちょっとしたトピックですがJavaのEnumは内部的にordinal()というメソッドを持ちます。これは列挙定数の位置順(初期定数はゼロ)を返します。例えばこの記事で紹介したCardの場合は以下のようになります。
1 2 3 4 5 6 |
System.out.println(Card.HEART.ordinal()); //0 System.out.println(Card.DIAMOND.ordinal()); //1 System.out.println(Card.SPADE.ordinal()); //2 System.out.println(Card.CLUB.ordinal()); //3 |
内部的には宣言した順に位置情報を持っているのだと覚えておくと今後の理解が深まるかもしれません。
もし今までEnumの使い方を知らなかった、使い方は知っていたがうまく利用できていなかった方は今日からでもぜひ使ってみてください。