対象:基本データ型を一通り学んだ後 / 「決まった選択肢の中から1つを選ぶ」型を理解します
enum(列挙型)は 「決まったいくつかの値のうちのどれか」 を表す型です。曜日、信号の色、トランプのスート、ゲームの状態など、取りうる値が限定的なものを表現するのに使います。
// 曜日を int で表現 int MON = 1; int TUE = 2; // ... int today = MON; // 問題点: // - int に何でも代入できてしまう // today = 999; // バグだがエラーにならない // - 何を表す数か分からない // if (today == 1) // 1 って何?
// 曜日を enum で定義
enum Day { MON, TUE, WED, THU, FRI, SAT, SUN }
Day today = Day.MON;
// メリット:
// - Day 型の変数には Day の値しか入れられない
// today = 999; // コンパイルエラー
// - 名前があるので意味が明確
// if (today == Day.MON)
// クラスと同じ場所に書ける
enum Day {
MON, TUE, WED, THU, FRI, SAT, SUN
}
| 項目 | 内容 |
|---|---|
| キーワード | enum(class と同じ位置に書く) |
| 列挙値の書き方 | カンマ区切り。慣習的に全て大文字 |
| セミコロン | 列挙値の最後には不要({ } で囲うだけ) |
Day today = Day.MON; // 「列挙型名.値名」で参照 System.out.println(today); // → MON(自動的に名前が文字列化される) // 別の値に変更 today = Day.FRI; System.out.println(today); // → FRI
Day d = MON; のように修飾子なしで書くと、変数 MON があるのかと解釈されてコンパイルエラー。必ず Day.MON と書く。
enum は switch 文の条件式に使える型のひとつです。switch の条件式には int, char, String, enum が使えます(switch 文は 06_制御文(if・switch) で詳しく扱います)。その型のひとつがこの enum です。
Day today = Day.WED;
switch (today) {
case MON: // ← Day. は不要(switch内では省略形)
System.out.println("月曜日");
break;
case TUE:
System.out.println("火曜日");
break;
case WED:
System.out.println("水曜日");
break;
case SAT:
case SUN:
System.out.println("週末");
break;
default:
System.out.println("その他の平日");
}
Day.MON ではなく MON と書きます。Java がswitchの条件式の型から自動的に補完してくれます。
enum の値は == で比較できます。同じ列挙値は同じインスタンスとして扱われるためです。
Day a = Day.MON; Day b = Day.MON; System.out.println(a == b); // → true(同じインスタンス) System.out.println(a.equals(b)); // → true(こちらでもOK)
== 比較は中身が同じでも false になることがあったが、enum は == で OK。文法のルールが違うので混同しないこと。
実習
04_Enum フォルダに EnumDemo.java を作って実行しましょう。
// enum をクラスと同じ場所に書く
enum Signal { RED, YELLOW, GREEN }
public class EnumDemo {
public static void main(String[] args) {
Signal sig = Signal.RED;
// ① 出力
System.out.println("信号: " + sig);
// ② switch で分岐
switch (sig) {
case RED:
System.out.println("止まれ");
break;
case YELLOW:
System.out.println("注意");
break;
case GREEN:
System.out.println("進め");
break;
}
// ③ == で比較
if (sig == Signal.RED) {
System.out.println("これは赤信号です");
}
}
}
| # | 変えてみること | 確認ポイント |
|---|---|---|
| 1 | Signal sig = Signal.GREEN; に変える | switch の分岐が変わって「進め」が出力されることを確認しましょう |
| 2 | Signal sig = "RED"; と書いてみる | String を enum 型に代入することはできず、コンパイルエラーになることを確認しましょう |
| 3 | case の中で Signal.RED と書いてみる | こちらもコンパイルエラー。case の中では RED と書く必要があります |
試験との対応
| よく問われること | 正しい答え |
|---|---|
| enum はどんな型か | 「決まった選択肢のうちの1つ」を表す型。基本データ型ではない |
| switch の条件式に使えるか | 使える(int, char, String, enum が使える) |
| case 内での書き方 | case MON: のように修飾子なしで書く |
| == による比較 | OK(同じ列挙値は同じインスタンス) |
曜日を表す enum Day を宣言する正しい書き方はどれか。
enum キーワードに続けて型名を書き、{ } の中に列挙値をカンマ区切りで並べる。列挙値の末尾にセミコロンは不要。クラスと同じ位置に書ける。
enum Day { MON, TUE, WED, THU, FRI, SAT, SUN } と宣言したとき、変数 d に「月曜日」を代入する正しい書き方はどれか。
"MON" は文字列なので Day 型に代入できない。MON 単独だと変数として解釈されてエラー。enum は new でインスタンス化するものではない(生成済みの定数を選ぶイメージ)。
switch 文で enum を扱うとき、case ラベルの書き方として正しいものはどれか。
Day.)を書くとエラー。Java が条件式の型から自動的に補完してくれる仕組み。
enum の値どうしを比較する方法として正しいものはどれか。
Day.MON はどこから呼んでも同じインスタンスなので == で正しく比較できる。.equals() も使えるが、enum では == が慣習的に使われる(String との違いに注意)。
サーティファイ Java 3級の試験範囲において、enum はどのカテゴリに含まれるか。
byte, short, int, long, float, double, char, boolean, enum として明記されている。本来「決まった選択肢を表す型」なので、データ型の仲間として扱われる。
| ポイント | 内容 |
|---|---|
| enum とは | 「決まった選択肢のうち1つ」を表す型。曜日・信号など |
| 宣言 | enum Day { MON, TUE, ... } |
| 参照 | Day.MON(型名.値名) |
| switch との連携 | case では case MON:(型名なし) |
| 比較 | == でOK(同じ列挙値は同じインスタンス) |
| 試験範囲 | 「Javaの扱うデータ」カテゴリに明記 |