読者です 読者をやめる 読者になる 読者になる

Jの衝動書き日記

さらりーまんSEの日記でございます。

Effective Javaの読書メモ 第6章 enumとアノテーション

java

 今回はenumの話。javaenumは本当に便利。定数定義では積極的に使っていこう。

項目30 int定数の代わりにenumを使用する

  • 数値に意味をもたせるなら、int定数よりもenumがよい
  • int定数は型安全性を提供しない
    • 異なる種別のint定義値を誤って代入してもエラーにはならない
  • int定数を表示可能な文字列に変換する簡単な方法はない
  • String定数は更に駄目
    • 文字列比較に依存するため、パフォーマンス問題になる可能性がある
    • 定数定義名を使用せずに定義している内容を直接ハードコーディングしていて、しかもその内容に誤字を含んでいた場合、コンパイル時にはすり抜けて実行時のバグになる

java enumの利点

  • コンパイル時の型安全性を提供
    • 異なる種類のenumは代入できない
  • 表示可能な文字列に変換するのは簡単
  • 振る舞いをもたせることが可能
  • 任意のフィールドやメソッドを追加できる
    • 特定の型に結びついた値を定義することが可能
例)
public enum PaperSize {

    A0(841,1189),
    A1(A0.height /2 , A0.width),
    A2(A1.height /2 , A1.width),
    A3(A2.height /2 , A2.width),
    A4(A3.height /2 , A3.width),
    A5(A4.height /2 , A4.width);
    
    private final int width;
    private final int height;
    private final int area;
    PaperSize(int width,int height) {
        this.width = width;
        this.height = height;
        this.area = width * height;
    }
    
    public int width()  { return width; }
    public int height() { return height;}
    public int area()   { return area;  }
}
int定数の場合は、A4_WIDTH,A4_HEIGTHなどとやらないといけない。
enumの場合はA4に結び付けられるのでわかりやすい

 

enumに対して異なる振る舞いを関連付ける方法

  • enum定義では抽象メソッドを定義
  • 各定数で抽象メソッドを実装
    • 継承によるswitch文の削除テクニックと同じ
例)
public enum Operation {
  PLUS("+") {
      double apply(double x, double y) { return x + y; }
  },
  MINUS("-") {
      double apply(double x, double y) { return x - y; }
  };
  
  private final String symbol;
  Operation(String symbol) { this.symbol = symbol; }
  @Override public String toString() { return symbol; }
  
  abstract double apply(double x, double y) ;
}

System.out.println(Operation.PLUS); → +
Operation.PLUS.apply(1,1); → 2
Operation.MINUS.apply(1,1); → 0

 

戦略enumという考え方

  • 複数enumが共通の振る舞いをする場合使う
  • 共通の振る舞いをenum化して、それをインスタンスとしてenumに持たせる
  • 詳細なコードはここでは略

enumはいつ使用するべきか?

  • 固定数の定数が必要な場合は常に使用すべき
  • コンパイル時にすべての可能な値がわかっている集合

enum使用のNGなケース

  • 序数からenumに関連付けられる値を決して導かない(ordinalメソッドenumの値とはしない) → 必要ならばインスタンスフィールドに値を保存すること

参考文献

Effective Java 第2版 (The Java Series)

Effective Java 第2版 (The Java Series)