1. 程式人生 > >Enum與最佳単例設計

Enum與最佳単例設計

構造函數 寫法 支持 參考 編譯程序 ati zab nbsp new

1 枚舉基礎

自定義一個枚舉類很簡單, 不過類型關鍵字是 enum, 不是 class, 也不是 interface.
public enum Action {
  UP, DOWN, LEFT, RIGHT
}

自定義的 Action枚舉 本質上還是一個 class, 反編譯可以看到如下定義:
public final class Action extends Enum {...}

enum關鍵字 定義了特殊的類, 繼承 java.lang.Enum, 由編譯程序處理, 我們直接寫類繼承 Enum類 會被編譯程序拒絕. 有必要了解下 java.lang.Enum類.

Enum 是個抽象類, 無法直接實例化.


public abstract class Enum<E extends Enum<E>> implements Comparable<E>, Serializable {
  private final String name;
  private final int ordinal;
  protected Enum(String name, int ordinal) {
    this.name = name;
    this.ordinal = ordinal;
  }
...
}
我們定義的 Action, 會繼承這個 Enum, 並且四個枚舉成員都將成為 static final 的 Action實例:

private Action(String s, int i){
  super(s, i);
}
public static final Action UP; //其他成員略
static{
  UP = new Action("UP", 0);
}

可以看出, Enum 的 name 記錄了枚舉成員的字符串名稱, ordinal 則記錄了枚舉成員的加入順序, Enum成員的排序和switch語法, 都是利用了 ordinal() 取得 int 值.
ordinal 的值是枚舉成員定義的順序(由0開始), 如果不想要這個順序, 可以加入 int 字段來主動編號:

  DOWN(2), UP(1), RIGHT(4), LEFT(3);


  private int number;
  private Action(int number){
    this.number = number;
  }

值得註意的是, 我們向上面這樣加入實例變量, 重寫私有構造, 最後都會編譯程序作為產生真的構造函數參考之用, 實際反編譯會變成這樣:
private Action(String s, int i, int number){
  super(s, i);
  this.number = number;
}
public static final DOWN; //其他成員略
...
static{
  DOWN = new Action("DOWN", 0, 2);
  ...
}
......

枚舉成員, 在 JVM 中只會存在單一實例. //static final

--------------------------------------------------------------------------------
2 最佳単例設計

枚舉類的特點, 決定了其在單例設計使用上的天然優勢.
Joshua Bloch大神說過: 單元素的枚舉類型已經成為實現Singleton的最佳方法.
 public enum EnumSingleton {
  INSTANCE;
  public EnumSingleton getInstance(){
    return INSTANCE;
  }
 }

優點:
寫法簡單優雅; 線程安全; 可應對反射攻擊; 序列化支持..
缺點:
因為已經繼承了 Enum, 所以不能再繼承了.

參考:
<<JDK7學習筆記>>林信良
http://www.importnew.com/24272.html
http://www.runoob.com/design-pattern/singleton-pattern.html
http://www.cnblogs.com/chiclee/p/9097772.html
https://www.cnblogs.com/lanxuezaipiao/p/3369962.html

Enum與最佳単例設計