網頁

2014年11月17日 星期一

Java Enum 列舉常數


撰寫 Java 的程式者會為了方便管理, 則會獨立一個 class 專門存放這些常數
以例子引導學習, 以下是一般列舉常數的作法

近來作程式開發, 我常常需要封裝 API 及 Exception
這邊就以字定義的 Exception 作為範例

一般列舉常數 


我的需求要一個 error_code 及相對應 code 的 infomation, 所以我做了以下 class
public class ReturnCode {

 public static final int SUCCESS = 200;
 public static final int CREATE_ERROR = 201;
 public static final int COPY_ERROR = 202;
 public static final int MOVE_ERROR = 203;
 public static final int RENAME_ERROR = 204;
 public static final int REPLACE_ERROR = 205;
 
 
 private static final Map map = new HashMap<>();
 static {
  map.put(SUCCESS, "成功");
  map.put(CREATE_ERROR, "建立檔案失敗");
  map.put(COPY_ERROR, "複製檔案失敗");
  map.put(MOVE_ERROR, "移動檔案失敗");
  map.put(RENAME_ERROR, "更新名稱失敗");
  map.put(REPLACE_ERROR, "覆蓋檔案失敗");
 }
 
 public static String getInfo(int code) {
  return map.get(code);
 }
}

以上這種定義方式為傳統的常數定義方法, 也有很多文章介紹透過 Switch 作列舉常數, 也可以多去看看
接下來定義自己需要的 Exception
public FileException(int code) {
 super(code + ": " + ReturnCode.getInfo(code));
}

並且故意輸出個 Exception 來看看結果
throw new FileException(ReturnCode.MOVE_ERROR);

看到以下結果
Exception in thread "main" phelim.org.test.FileException: 203: 移動檔案失敗
 at phelim.org.test.Test.main(Test.java:5)

當然作以下的動作一樣可以達成效果
throw new FileException(203);

這邊 FileException 的建構式中是允許 Int 參數輸入,所以以下這種寫法語法上也沒錯
throw new FileException(500);

但輸出的結果卻會是 null 造成了不嚴謹的問題
Exception in thread "main" phelim.org.test.FileException: 500: null
 at phelim.org.test.Test.main(Test.java:5)

所以我們可以透過 Enum 來解決這個問題

Enum 列舉常數


以下是我定義的 Enum 類別
public enum ReturnCodeEnum {
 
 SUCCESS(200, "成功"),
 CREATE_ERROR(201, "建立檔案失敗"),
 COPY_ERROR(202, "複製檔案失敗"),
 MOVE_ERROR(203, "移動檔案失敗"),
 RENAME_ERROR(204, "更新名稱失敗"),
 REPLACE_ERROR(105, "覆蓋檔案失敗");
 
 private final int code;
 private final String info;
 
 private ReturnCodeEnum(int code, String info) {
  this.code = code;
  this.info = info;
 }
 
 public int getCode() {
  return this.code;
 }

 public String getInfo() {
  return this.info;
 }
}

Exception 的建構式也改成接收 Enum 的類別
public FileException(ReturnCodeEnum returnCodeEnum) {
  super(returnCodeEnum.getCode() + ": " + returnCodeEnum.getInfo());
 }

輸出方式與結果如下
throw new FileException(ReturnCodeEnum.MOVE_ERROR);

Exception in thread "main" phelim.org.test.FileException: 203: 移動檔案失敗
 at phelim.org.test.Test.main(Test.java:7)

由於接收的參數為 Enum 類別, 所以不會遇上自己定義的幾個項目以外的狀況,此作法較嚴謹
有時候我們可能還是希望透過 code 取得 info 的資訊, 于是乎我們使用一些特殊作法在 Enum 的類別中
private static Map returnMap = new HashMap<>();;
static {
 for (ReturnCodeEnum r : ReturnCodeEnum.values()) {
  returnMap.put(r.code, r.info);
 }
}
 
public static String getInfoByCode(ReturnCodeEnum r) {
 return returnMap.get(r.code);
}

如此一來我們就可以透過 getInfoByCode 的 Method 來取得 Info 資訊
System.out.println(ReturnCodeEnum.getInfoByCode(ReturnCodeEnum.COPY_ERROR));

複製檔案失敗

以上是一些 Enum 的簡易用法, 按照我自己的經驗, 光看別人文章都不會懂
所以...看看當作學習, 當某天遇到的時候就會慢慢明白了。

沒有留言:

張貼留言