關於 Java Enum,我的認識

Enum 在 JDK 1.5 後始出現,大大提昇了開發者在撰寫程式的效率以及維護的便利性,同時也增進了程式的安全性,以下以幾個常見的 snippets 來幫助自己認識 Java 的 Enum

public enum Genres {
    Alternative, Blues, Classical, Country, Electronic, 
    Hardcore, Hip-Hop, Indie, Jazz, Pop, Punk, Rock
}

上述的程式碼是最基本的 Java enum 宣告的一個例子,enum 本身有幾個特性:

  1. Type-Safe: 若傳入非該 enum 內宣告的數值時,編譯時就會立刻回報錯誤
  2. enum 的 print out 出來的值,是有語意上的意義的
  3. 可以使用 switch 敘述
  4. enum 其實就是一種 singleton 的 generics (泛型)
  5. 很容易的就能夠 iterate 所有的元素(透過 EnumSet.allOf()

透過 Java 語言本身所給 enum 型別所撰寫的 toString() 方法,若以上述的 Genres 類別來說,Genres.Blues.toString() 所得到的值正好就會是 Blues,所以說 enum 型別的物件非常適合用來取代一般開發者常會用到字串型態的的 Constants 類別!

我們也可以藉由給 enum 中的 element 指定特定型別的參數,來使得我們自訂的 enum 物件更加強大,如:

public enum CountryCode {
    Australia(61),
    China(86),
    Japan(81),
    Taiwan(886)

    CountryCode(int code) {
        this.code = code;
    }

    private int code;

    public int getCode() {
        return code;
    }
}

如此一來,透過 CountryCode.Taiwan.getCode() 便能取得台灣的國碼,並且爾後在維護上也相當的方便,只需要在 CountryCode 中新增相對應的國家名稱與國碼、修改該國家的國碼,或者從 CountryCode 中刪除該國家的紀錄即可。
修改完畢後再度編譯時,若我們採用這種方式便能夠直接在IDE中或編譯時期發現程式的錯誤,對於開發者來說相當友善!

對於國碼的例子,那麼我們是否有辦法透過國碼如886,來得到所對應 CountryCode 中的國家的實例呢?
答案是可以的,透過加入以下的 snippet:

public enum CountryCode {
    //...省略


    private static HashMap<Integer, CountryCode> codeMap = new HashMap<Integer, CountryCode>();
    static {
        for (CountryCode country : EnumSet.allOf(CountryCode.class)) {
            codeMap.put(country.getCode(), country);
        }
    }

    public CountryCode getCountryByCode(int code) {
        return codeMap.get(code);
    }
}

我們便可以透夠 CountryCode.getCountryByCode(int code) 這個方法來取得該給定的國碼所對應的國家的 CountryCode 實例,作為後續的使用(如在switch中使用)

透過 Override Enum 的 toString() 方法,可以很方便的印出我們想要的值,譬如:

public enum Action {
    GET("get"),
    POST("post"),
    PUT("put"),
    DELETE("delete")

    Action(String action) {
        this.action = action;
    }

    private String action;
    private String HOST = "http://YOUR_HOST_HERE/%s";

    @Override
    public String toString() {
        return String.format(HOST, action);
    }
}

以上述的 snippet 為例,透過 Action.toString() 方法便可以得到 http://YOUR_HOST_HERE/action 的 URL 了。

comments powered by Disqus