Javaでenumを使って列挙型を利用する方法【初心者向け】
初心者向けにJavaで書くenumを使った列挙型の使い方について解説。enumの書き方から実際に書いてみたサンプルを紹介しながら説明しています。Javaエンジニアを目指している人は今のうちに覚えておきましょう。
テックアカデミーマガジンは受講者数No.1のプログラミングスクール「テックアカデミー」が運営。初心者向けにプロが解説した記事を公開中。現役エンジニアの方はこちらをご覧ください。 ※ アンケートモニター提供元:GMOリサーチ株式会社 調査期間:2021年8月12日~8月16日 調査対象:2020年8月以降にプログラミングスクールを受講した18~80歳の男女1,000名 調査手法:インターネット調査
今回はJavaで定数(固定された値)をまとめて扱えるenumについて、テックアカデミーのメンター(現役エンジニア)が実際のコードを使用して初心者向けに解説します。
enumは列挙型といって、決まった値をひとまとめにしたデータです。
Javaだけでなく、C言語にも存在しています。
ですが、Javaのenumはクラスとして定義し、メソッド(クラスの機能)やフィールド(データの値)を追加できます。
もし、1つの値と名前を結び付けて使うだけならfinal修飾子があります。
詳しくは「Javaの定数宣言とfinalについて現役エンジニアが解説【初心者向け】」を参照してください。
目次
そもそもJavaについてよく分からないという方は、Javaとは何なのか解説した記事を読むとさらに理解が深まります。
また、Javaのクラスについてわからない方は「Javaのクラス宣言について現役エンジニアが解説【初心者向け】」、「Javaのクラスメソッドについて現役エンジニアが解説【初心者向け】」の記事をご覧ください。
まずは基礎的な使い方をご紹介します。
ここではenum、列挙型についての勉強をしていこう。enumは定数と関係があるんだけど、ゆかりちゃんは「定数」分かるよね?
定数?たしか固定された値でしたね。列挙型というのは何ですか?
列挙型とは複数の定数を1つにまとめておくことができる型だよ。うまく使うことで定数の扱いがしやすくなるんだ。簡単な例で見てみよう。
分かりました!
enumとは?
enumは列挙型と呼ばれています。
列挙型は、どの範囲になり得るかという値の幅をセットにしたデータです。
たとえば、曜日を扱う列挙型なら「月曜」から「日曜」までの7つの値だけを使用すると明確に宣言できます。
enumの基本的な書き方
enumの宣言
例として性別(Gender)をenumで列挙型にしてみましょう。
例
男性(MALE)、女性(FEMALE)のいずれかの値である列挙型 Genderを宣言します。
enum Gender{ MALE, FEMALE }
※列挙名を大文字にしているのは、定数で命名する場合の慣習です。
プログラムとしては小文字でも動きますが、大文字で命名することにより通常の変数ではなく定数であるとプログラマーが容易に見分けられます。
enumの使い方
宣言した列挙型はint型などと同じように使用できます。
列挙型として宣言された変数に代入できるのは、列挙型で指定された値(またはnull。値が入っていない意味)に限られます。
例えばGenderなら gender_type は、Gender.MALE または Gender.FEMALE のどちらかを代入できます。
例
gender_typeをGenderで宣言し、男性のデータを入れて表示します。
public class Main { enum Gender{ MALE, FEMALE } public static void main(String[] args) throws Exception { Gender gender_type = Gender.MALE; System.out.println("性別:" + gender_type); } }
実行結果
性別:MALE
gender_typeに代入された「MALE」が出力されます。
enumの実用的な使い方
enumで宣言した列挙型は決まった範囲の値になるので、エラー処理を書く必要を減らせます。
列挙型の性質から、エラーを出しにくいシンプルなプログラムにできます。
switch文でenumを使う
Javaではswicth文に列挙型が使用可能です。
enumをswitch文で使えば、値を列挙名に限定できるのでエラー処理が簡単にできます。
例
男性か女性かで出力するメッセージを変えます。
public class Main { enum Gender{ MALE, FEMALE } public static void main(String[] args) throws Exception { Gender gender_type = Gender.FEMALE; switch(gender_type){ case MALE: System.out.println("男性です"); break; case FEMALE: System.out.println("女性です"); break; } } }
実行結果
女性です
gender_typeが”FEMALE”だったので「case FEMALE:」以下が実行されます。
※Javaではenumの列挙型の値をswitch文のcaseで指定するときに型名(上記のコード例ではGender)を省略できます。
メソッドの戻り値や引数としてenumを使う
メソッドの戻り値や引数としてenumを使えば、決められた値のどれかになるため、余分なエラー処理を書く必要がなく処理をシンプルにできます。
例
get_genderメソッドに渡した引数の文字列に対応する列挙型 Genderの値を返します。
get_genderの戻り値はGenderの値(またはnull)以外にはならないので、戻り値のエラーチェックを簡単にできます。
public class Main { enum Gender{ MALE, FEMALE } public static void main(String[] args) throws Exception { Gender gender_type = get_gender("女子"); System.out.println(gender_type); } public static Gender get_gender(String gender_str){ Gender type = null; switch(gender_str){ case "男": case "男性": case "男子": type = Gender.MALE; break; case "女": case "女性": case "女子": type = Gender.FEMALE; break; } return type; } }
実行結果
FEMALE
enumの標準機能
列挙型 enumであれば最初から使えるメソッドが標準で用意されています。
enumで宣言した順番を取得したり、ループで使うために配列で取得したりできます。
ordinalメソッドで順番を取得する
ordinalは、enumで宣言した順番を取得するメソッドです。
0から数えます。
例
Gender.MALEが宣言された順番を、最初の値を0として数えた番号を出力します。
Gender.MALEは最初に宣言されているので順番は0です。
Gender.FEMALEなら2番目の1です。
public class Main { enum Gender{ MALE, FEMALE } public static void main(String[] args) throws Exception { Gender gender_type = Gender.MALE; System.out.println(gender_type.ordinal()); System.out.println(gender_type); } }
実行結果
0 MALE
nameメソッドで文字列と比較する
nameメソッドは、宣言された値の名前を返します。
列挙名を文字列で取得できるので文字列と比較できます。
例
列挙型 Genderで宣言されたtypeの列挙名が、文字列 “FEMALE” かを判定します。
public class Main { enum Gender{ MALE, FEMALE } public static void main(String[] args) throws Exception { Gender type = Gender.FEMALE; if(type.name() == "FEMALE"){ System.out.println("女性です"); } else { System.out.println("女性ではありません"); } } }
実行結果
女性です
※通常、文字列変数の比較にはequalsメソッドが使われますが、定数同士の比較(列挙名も含む)には==演算子を使用できます。
※列挙型で宣言した変数(上記のサンプルでは「type」)をそのまま使った場合は、toStringメソッドが呼び出されて列挙名の文字列が返されます。toStringはnameメソッドと違ってメソッドを書き換えるオーバーライドができます。以下のコードは同じ処理です。
System.out.println(type);
System.out.println(type.toString());
valuesで列挙の配列を取得
valuesは列挙値を配列で取得します。
ループで列挙名を使う場合に便利です。
例
列挙名をすべて出力します。
public class Main { enum Gender{ MALE, FEMALE } public static void main(String[] args) throws Exception { for(Gender type : Gender.values()){ System.out.println(type); } } }
実行結果
MALE FEMALE
拡張for文ですべての値を取り出します。
valueOfメソッドで文字列に対応したenumを返す
valueOfメソッドは文字列に対応した列挙名のenum定数を返します。
指定した文字列の定数を取得できます。
例
enumの列挙型 Genderに文字列 “MALE”で宣言されている定数を取得します。
public class Main { enum Gender{ MALE, FEMALE } public static void main(String[] args) throws Exception { Gender type; type = Gender.valueOf("MALE"); System.out.println(type); } }
実行結果
MALE
※定義されていない列挙名を指定すると例外(エラー)が発生します。
※単に比較したり出力する場合と違い、代入するときは変数の型が同じでないと例外(エラー)が発生します。
以下のコードは正しい例と正しくない例です。
(正しい例)Gender type = Gender.valueOf(“MALE”);
(誤りの例)Gender type = “MALE”;
enumの応用
Javaでは列挙型のenumをクラスのように定義して機能を拡張できます。
enum型に日本語の名前をつけたり、任意の数値をセットで持たせたりしたい場合は、enum型を宣言するときにフィールド変数やメソッドを定義します。
日本語の名前を使う
列挙型で日本語の名前を使うには、直接列挙名には指定できないので、enum型を宣言するときにフィールド変数を定義します。
列挙名と同じようにフィールド変数のやり取りを内部に限定する場合、値のセットと取得のためにメソッドを定義する必要があります。
それでコンストラクタ(作成時に呼び出されるメソッド)とゲッター(メンバー変数を取得するメソッド)も一緒に定義します。
例
enum Genderに日本語の名前も一緒に定義し、getJnameで日本語名を取得できるようにします。
public class Main { enum Gender{ MALE("男性"), FEMALE("女性"); final String jname; Gender(String name){ this.jname = name; } String getJname(){ return jname; } } public static void main(String[] args) throws Exception { Gender type = Gender.MALE; System.out.println(type.getJname()); } }
実行結果
男性
まず、コンストラクタ Genderで日本語名をjnameにセットします。
日本語名を取得するにはgetJnameというメソッドを定義できており、これが this(Gender)のjnameの値を返却していることが分かります。
※final修飾子で宣言した変数 jnameは、代入後には変更できなくなります。コンストラクタで代入後は変更できないので、定数のようにふるまいます。
※enumにメソッドやフィールド変数を定義する場合、最後の列挙名(上記のコードでは「FEMALE(“女性”)」)の後ろに「;」セミコロンをつけます。
列挙型と定数の違い
列挙型
列挙型は複数の値のうち、どれかを示すデータ型です。
値には自動的に順番ごとに番号がつけられます。
通常は順番の番号そのものには意味がないことがほとんどです。
たとえば曜日を扱う列挙型で、SUNDAYが最初なら順番の数字は0、次のMONDAYなら1 といった具合です。
ただし、列挙型を1つずつ取り出す場合や他のプログラムで使用する場合を考えて、列挙型の並び順や何の値から始めるか(たとえばSUNDAYから始めるか、MONDAYから始めるか)などは考える必要があります。
定数
定数は変更されない1つの値に名前をつけた型です。
Javaでは、変数をfinalで宣言します。
定数はそれぞれ、1つだけの固定された値を持つことができます。
たとえば pai という名前の定数に 3.14 の値を宣言できます。
Javaの定数やfinal修飾子について詳しくは「Javaの定数宣言とfinalについて現役エンジニアが解説【初心者向け】」の記事をご覧ください。
まとめると列挙型のenumは上のように、同じカテゴリーに属するものを入れる感じだね。
今回だと性別ですね。列挙型名も自由に付けられるんですか?
そうだね。なので自分で分かりやすい名前にするのがいいと思うよ。
まとめ
今回はJavaのenumの特有な使い方を紹介しました。
しかしこれだけでなく、Javaのenumは型であることから、さまざまな機能を持つことができます。
今回は初歩的な使い方がメインでしたが、enumの可能性はまだまだ底が見えません。
C言語などのほかの言語を扱ったことがある人はもちろんのこと、Javaから始めた人も多くの可能性をenumから感じられたのではないでしょうか。
enumを活用するとコードが見やすくなるし、間違った値を入れることを防ぐこともできるんだ。
便利な機能なんですね。
種類や数がはっきりしている定数に関しては、できるだけenumを使うことを検討してみよう。
少しずつ練習してみます。ありがとうございました!
Javaを学習中の方へ
これで解説は終了です、お疲れさまでした。
- つまずかず「効率的に」学びたい
- 副業や転職後の「現場で使える」知識やスキルを身につけたい
プログラミングを学習していて、このように思ったことはありませんか?
テックアカデミーのJavaコースでは、第一線で活躍する「プロのエンジニア」が教えているので、効率的に実践的なスキルを完全オンラインでしっかり習得できます。
合格率10%の選考を通過した、選ばれたエンジニアの手厚いサポートを受けながら、JavaやServletの技術を使ったWebアプリケーション開発を学べます。
まずは一度、無料体験で学習の悩みや今後のキャリアについて話してみて、「現役エンジニアから教わること」を実感してみてください。
時間がない方、深く知ってから体験してみたい方は、今スグ見られる説明動画から先に視聴することをおすすめします!