列舉型別 是一種特殊的資料型態,能讓變數的值取自一組預先定義的常數。
這個變數必須等於其中一個為它預先定義好的值。
常見的例子包括羅盤方位(NORTH、SOUTH、EAST 和 WEST 等值)以及一週中的每一天。
因為它們是常數,列舉型別的欄位名稱會使用大寫字母。
在 Java 程式語言中,你可以使用enum關鍵字來定義列舉型別。
例如,你可以這樣定義一個代表一週中各天的列舉型別:
public enum DayOfWeek {
SUNDAY,
MONDAY,
TUESDAY,
WEDNESDAY,
THURSDAY,
FRIDAY,
SATURDAY
}
當你需要表示一組固定的常數時,就應該使用列舉型別。 這包括自然的列舉型別,例如太陽系中的行星,以及在編譯時就知道所有可能值的資料集,例如選單上的選項、命令列旗標等等。
以下程式碼示範如何使用上面定義的DayOfWeek列舉:
public class Shop {
public String getOpeningHours(DayOfWeek dayOfWeek) {
switch (dayOfWeek) {
case MONDAY:
case TUESDAY:
case WEDNESDAY:
case THURSDAY:
case FRIDAY:
return "9am - 5pm";
case SATURDAY:
return "10am - 4pm"
case SUNDAY:
return "Closed.";
}
}
}
var shop = new Shop();
shop.getOpeningHours(DayOfWeek.WEDNESDAY);
// => "9am - 5pm"
Java 的列舉型別遠比其它語言中的同類功能強大得多。
enum 宣告會定義一個_類別_(稱為_列舉型別_)。
列舉類別的主體可以包含方法和其他欄位:
public enum Rating {
GREAT(5),
GOOD(4),
OK(3),
BAD(2),
TERRIBLE(1);
private final int numberOfStars;
Rating(int numberOfStars) {
this.numberOfStars = numberOfStars;
}
public int getNumberOfStars() {
return this.numberOfStars;
}
}
在Rating列舉型別的成員上呼叫getNumberOfStars方法:
Rating.GOOD.getNumberOfStars();
// => 4
在這個練習中,你會處理日誌行。
每一行日誌都是格式如下的字串:"[<LVL>]: <MESSAGE>"。
以下是不同的日誌等級:
TRC(追蹤)DBG(除錯)INF(資訊)WRN(警告)ERR(錯誤)FTL(致命)你有 3 個任務。
定義一個LogLevel列舉,其中包含 6 個元素,分別對應上述的日誌等級。
TRACEDEBUGINFOWARNINGERRORFATAL接著,實作LogLine.getLogLevel()方法,回傳一行日誌解析後的日誌等級:
var logLine = new LogLine("[INF]: File deleted");
logLine.getLogLevel();
// => LogLevel.INFO
可惜的是,偶爾某些日誌行會有未知的日誌等級。
為了優雅地處理這些日誌行,請在LogLevel列舉中加入一個UNKNOWN元素,在解析到未知的日誌等級時應該回傳它:
var logLine = new LogLine("[XYZ]: Overly specific, out of context message");
logLine.getLogLevel();
// => LogLevel.UNKNOWN
日誌行的日誌等級相當冗長。
為了減少儲存日誌行所需的磁碟空間,我們發展出一種簡短格式:"[<ENCODED_LEVEL>]:<MESSAGE>"。
編碼後的日誌等級,就是將日誌等級簡單對應到一個數字:
UNKNOWN - 0
TRACE - 1
DEBUG - 2
INFO - 4
WARNING - 5
ERROR - 6
FATAL - 42
實作LogLine.getOutputForShortLog()方法,用來輸出縮短後的日誌行格式:
var logLine = new LogLine("[ERR]: Stack Overflow");
logLine.getOutputForShortLog();
// => "6:Stack Overflow"