[Java] 覚えておきたいenumの使い方

どうも、tatsuです!

今回はJavaのenumの使い方について説明していこうと思います。

enumとは

enumは列挙型と言われ、定数を管理したい場合などに使うと便利です。

例えば以下のような場合があったとします。

// 挨拶を出力するメソッド
public void outputGreeting(int greetingType){
  if(greetingType == 1){
    System.out.println("おはよう");
  }else if(greetingType == 2){
    System.out.println("こんにちは");
  }else{
    System.out.println("こんばんは");
  }
}

これではgreetingTypeの取りうる値が分かりずらいですよね。
enumを使うと以下のように書くことができます。

// greetingTypeの取りうる値
public enum GreetingType{
  MORNING,
  AFTERNOON,
  NIGHT
}

// 挨拶を出力するメソッド
public void outputGreeting(GreetingType greetingType){
  if(greetingType == GreetingType.MORNING){
    System.out.println("おはよう");
  }else if(greetingType == GreetingType.AFTERNOON){
    System.out.println("こんにちは");
  }else{
    System.out.println("こんばんは");
  }
}

enumクラスには、使いたい選択肢をそのまま定義することができます。

このようにすることでoutputGreetingメソッドの引数にはGreetingTypeクラスしか渡せないため、マジックナンバーを他の人が使うこともありません。→マジックナンバーとは

値を保持する

enumクラスでは、各選択肢(列挙子といいます)に値を持たせることができます。

列挙子の隣に括弧をつけて中に値を書きます。
また、コンストラクタと値のフィールド、値を取得するメソッドも追加しておく必要があります。

以下に例をあげます。

// greetingTypeの取りうる値
public enum GreetingType{
  MORNING("おはよう"),
  AFTERNOON("こんにちは"),
  NIGHT("こんばんは");

  // 値フィールド
  private String japaneseGreeting;

  // コンストラクタ 必ずprivate
  private GreetingType(String japaneseGreeting){
    this.japaneseGreeting = japaneseGreeting;
 }

  // 値取得メソッド
  public String getJapaneseGreeting(){
    return japaneseGreeting;
  }
}

// 挨拶を出力するメソッド
public void outputGreeting(GreetingType greetingType){
  // 引数でわたってきたGreetingTypeの持っている値を取得するだけなので1行で済む
  System.out.println(greetingType.getJapaneseGreeting());
}

もちろん複数の値をとることもできます。

// greetingTypeの取りうる値
public enum GreetingType{
  MORNING("おはよう","good morning"),
  AFTERNOON("こんにちは","hello"),
  NIGHT("こんばんは","good evening");

  // 値フィールド
  private String japaneseGreeting;
  private String englishGreeting;

  // コンストラクタ 必ずprivate
  private GreetingType(String japaneseGreeting, String englishGreeting){
    this.japaneseGreeting = japaneseGreeting;
    this.englishGreeting = englishGreeting;
 }

  // 値取得メソッド
  public String getJapaneseGreeting(){
    return japaneseGreeting;
  }
  public String getEnglishGreeting(){
    return englishGreeting;
  }
}

enumの持つ値をループで回す

「特定の値がenumクラスの値と一致しているか」を判定したいときや「中身を全て出力する」ときに使うのがループです。

enumの中身をループで回してすべての挨拶を出力します。

// greetingTypeの取りうる値
public enum GreetingType{
  MORNING("おはよう"),
  AFTERNOON("こんにちは"),
  NIGHT("こんばんは");

  // 値フィールド
  private String japaneseGreeting;

  // コンストラクタ 必ずprivate
  private GreetingType(String japaneseGreeting){
    this.japaneseGreeting = japaneseGreeting;
 }

  // 値取得メソッド
  public String getJapaneseGreeting(){
    return japaneseGreeting;
  }
}

// すべての挨拶を出力するメソッド
public void outputAllGreeting(){
  // GreetingType.values() で全ての値を取得し、順番にgreetingTypeに格納しています
  for(GreetingType greetingType : GreetingType.values()){
    System.out.println(greetingType.getJapaneseGreeting());
  }
}

特定の列挙子だけメソッドの挙動を変える(オーバーライドする)

今度は特定の列挙子のときだけメソッドの挙動を変えてみたいと思います。

// greetingTypeの取りうる値
public enum GreetingType{
  MORNING("おはよう"),
  AFTERNOON("こんにちは"){
    @Override public String getJapaneseGreeting(){
      return "hello";
    }
  },
  NIGHT("こんばんは");

  // 値フィールド
  private String japaneseGreeting;

  // コンストラクタ 必ずprivate
  private GreetingType(String japaneseGreeting){
    this.japaneseGreeting = japaneseGreeting;
 }

  // 値取得メソッド
  public String getJapaneseGreeting(){
    return japaneseGreeting;
  }
}

// すべての挨拶を出力するメソッド
public void outputAllGreeting(){
  // AFTERNOONのときだけは"こんにちは"ではなく"hello"と出力されます。
  for(GreetingType greetingType : GreetingType.values()){
    System.out.println(greetingType.getJapaneseGreeting());
  }
}

AFTERNOONの括弧のあとに{}をつけ、その中でgetJapaneseGreetingメソッドをオーバーライドしています。

こうすることで、特定の列挙子の時だけ他の列挙子と違う動きをさせることができます。

まとめ

いかがでしたか?

enumクラスはとても便利なので、ぜひ使い方をマスターして使いこなしてみてください!

それでは!

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です