Java の enum ってクラスだったんだ…

Effective Java 第2版 (The Java Series) を読み始めたんですが、その中で enum が取り上げられていました。
enumJava に追加された事は知ってましたが、中身までは調べておらずどうせ他の言語(C とか C#) と同じだと思ってたのでビックリ!


C# の場合、メソッドのパラメータやプロパティに Enum を指定しても不適切な値が渡されるケースがあるので、厳密には型チェックの必要があります。

C#

using System;

public enum Style
{
  太字, 
  斜体, 
  下線, 
  取り消し線, 
}

class Program
{
  static void Main(string[] args)
  {
    Write(Style.太字);
    Write(Style.斜体);
    Write(Style.下線);
    Write(Style.取り消し線);
    Write((Style)16); // コンパイルエラーにならない

  }
  static void Write(Style s)
  {
    // 厳密な型チェックを行う必要がある!
    if (!Enum.IsDefined(typeof(Style), s))
    {
      Console.WriteLine("Not Define {0}", s);
      return;
    }

    Console.WriteLine(s);
  }
}

Java

public class EnumTest {
  public static void main(String[] args) {
    write(Style.太字);
    write(Style.斜体);
    write(Style.下線);
    write(Style.取り消し線);
  }
  public static void write(Style s) {
    System.out.println(s);
  }
}
enum Style { 太字, 斜体, 下線, 取り消し線, }

Javaenum はイケてますね!


上で提示した Style っていう enum は複数の値を組み合わせて使う想定の場合どうでしょう?C# では、列挙値をビットに見立ててビット演算を使います。enum には、MSDN FlagsAttribute クラス を付与しましょう!

using System;

[Flags()]
public enum Styles
{
  太字 = 0x01, 
  斜体 = 0x02, 
  下線 = 0x04, 
  取り消し線 = 0x08, 
}

class Program
{
  static void Main(string[] args)
  {
    Write(Styles.太字);
    Write(Styles.斜体);
    Write(Styles.下線);
    Write(Styles.取り消し線);
    Write(Styles.太字 | Styles.斜体);
    Write(Styles.斜体 | Styles.下線 | Styles.取り消し線);

    Write((Styles)16); // コンパイルエラーにならない

  }
  static void Write(Styles s)
  {
/*  FlagsAttribute が付与されている場合、Enum.IsDefined では正しく検証出来ない。独自のチェック機構が必要!今回は省いてます。
    if (!Enum.IsDefined(typeof(Styles), s))
    {
      Console.WriteLine("Not Define {0}", s);
      return;
    }
*/
    Console.WriteLine(s);
  }
}

Java では、ビット演算は出来ないなぁと思ってたら、Oracle Technology Network for Java Developers | Oracle Technology Network | Oracle を使って似た様な事が出来るみたい。