Java Switch Expression (Java 14+)
Java 14 引入了 Switch Expression(切換表達式),這是一種更簡潔、更現代化的 switch 語法。與傳統的 switch 敘述不同,Switch Expression 可以回傳值,並且使用箭頭語法 (->) 讓程式碼更清晰。
傳統 switch vs Switch Expression
傳統 switch 敘述
String dayType;
int day = 3;
switch (day) {
case 1:
case 2:
case 3:
case 4:
case 5:
dayType = "工作日";
break;
case 6:
case 7:
dayType = "假日";
break;
default:
dayType = "未知";
}
System.out.println(dayType); // 工作日
Switch Expression(箭頭語法)
int day = 3;
String dayType = switch (day) {
case 1, 2, 3, 4, 5 -> "工作日";
case 6, 7 -> "假日";
default -> "未知";
};
System.out.println(dayType); // 工作日
Switch Expression 的優勢:
- 可以直接回傳值並賦予變數
- 多個 case 可以用逗號合併
- 不需要
break,避免 fall-through 錯誤 - 程式碼更簡潔易讀
箭頭語法 (->)
箭頭語法是 Switch Expression 的核心特色:
int month = 8;
String season = switch (month) {
case 3, 4, 5 -> "春天";
case 6, 7, 8 -> "夏天";
case 9, 10, 11 -> "秋天";
case 12, 1, 2 -> "冬天";
default -> "無效月份";
};
System.out.println(season); // 夏天
多行程式碼區塊與 yield
當 case 需要執行多行程式碼時,使用大括號 {} 包裹,並用 yield 關鍵字回傳值:
int score = 85;
String grade = switch (score / 10) {
case 10, 9 -> "A";
case 8 -> {
System.out.println("成績不錯!");
yield "B";
}
case 7 -> "C";
case 6 -> "D";
default -> {
System.out.println("需要加油!");
yield "F";
}
};
System.out.println("等級: " + grade);
// 成績不錯!
// 等級: B
yield 是 Java 14 新增的關鍵字,專門用於 Switch Expression 中回傳值。
冒號語法搭配 yield
Switch Expression 也可以使用傳統的冒號語法 (:),但需要用 yield 回傳值:
int day = 3;
String dayName = switch (day) {
case 1:
yield "星期一";
case 2:
yield "星期二";
case 3:
yield "星期三";
case 4:
yield "星期四";
case 5:
yield "星期五";
case 6:
yield "星期六";
case 7:
yield "星期日";
default:
yield "無效";
};
System.out.println(dayName); // 星期三
注意:使用冒號語法時不能用 break,必須用 yield。
完整性檢查(Exhaustiveness)
Switch Expression 要求必須處理所有可能的值。對於 enum 類型,編譯器會檢查是否涵蓋所有列舉值:
enum Color { RED, GREEN, BLUE }
Color color = Color.GREEN;
String colorName = switch (color) {
case RED -> "紅色";
case GREEN -> "綠色";
case BLUE -> "藍色";
// 不需要 default,因為已涵蓋所有 enum 值
};
System.out.println(colorName); // 綠色
對於其他類型(如 int、String),通常需要 default 分支:
int value = 5;
String result = switch (value) {
case 1 -> "一";
case 2 -> "二";
case 3 -> "三";
default -> "其他"; // 必須有 default
};
搭配 enum 使用
Switch Expression 與 enum 搭配非常好用:
enum Operation { ADD, SUBTRACT, MULTIPLY, DIVIDE }
int calculate(Operation op, int a, int b) {
return switch (op) {
case ADD -> a + b;
case SUBTRACT -> a - b;
case MULTIPLY -> a * b;
case DIVIDE -> {
if (b == 0) {
throw new ArithmeticException("除數不能為零");
}
yield a / b;
}
};
}
// 使用
System.out.println(calculate(Operation.ADD, 10, 5)); // 15
System.out.println(calculate(Operation.MULTIPLY, 10, 5)); // 50
回傳不同型別
Switch Expression 的所有分支必須回傳相同或相容的型別:
// 正確:所有分支都回傳 String
String result = switch (value) {
case 1 -> "一";
case 2 -> "二";
default -> "其他";
};
// 正確:int 和 double 相容,結果是 double
double number = switch (type) {
case "int" -> 100;
case "double" -> 99.9;
default -> 0;
};
不回傳值的 Switch Expression
雖然名為 Expression,但也可以不回傳值,單純用於執行程式碼:
int action = 2;
switch (action) {
case 1 -> System.out.println("新增");
case 2 -> System.out.println("編輯");
case 3 -> System.out.println("刪除");
default -> System.out.println("無效操作");
}
// 編輯
這種用法結合了箭頭語法的簡潔,但不需要賦值給變數。
null 處理 (Java 21+)
Java 21 開始,switch 可以直接處理 null 值:
String str = null;
String result = switch (str) {
case null -> "空值";
case "hello" -> "你好";
case "bye" -> "再見";
default -> "其他";
};
System.out.println(result); // 空值
在 Java 21 之前,對 null 進行 switch 會拋出 NullPointerException。
Pattern Matching (Java 21+)
Java 21 正式支援 switch 的 Pattern Matching:
Object obj = "Hello";
String result = switch (obj) {
case Integer i -> "整數: " + i;
case String s -> "字串: " + s;
case Double d -> "浮點數: " + d;
case null -> "空值";
default -> "未知類型";
};
System.out.println(result); // 字串: Hello
搭配 when 條件
Object obj = 25;
String result = switch (obj) {
case Integer i when i < 0 -> "負數";
case Integer i when i == 0 -> "零";
case Integer i when i > 0 -> "正數";
case String s when s.isEmpty() -> "空字串";
case String s -> "字串: " + s;
case null -> "空值";
default -> "其他";
};
System.out.println(result); // 正數
Record Pattern (Java 21+)
搭配 Record 類型進行解構:
record Point(int x, int y) {}
Object obj = new Point(10, 20);
String result = switch (obj) {
case Point(int x, int y) when x == 0 && y == 0 -> "原點";
case Point(int x, int y) when x == y -> "對角線上";
case Point(int x, int y) -> "座標: (" + x + ", " + y + ")";
default -> "不是 Point";
};
System.out.println(result); // 座標: (10, 20)
實用範例
HTTP 狀態碼處理
int statusCode = 404;
String message = switch (statusCode) {
case 200 -> "OK";
case 201 -> "Created";
case 400 -> "Bad Request";
case 401 -> "Unauthorized";
case 403 -> "Forbidden";
case 404 -> "Not Found";
case 500 -> "Internal Server Error";
case 502 -> "Bad Gateway";
case 503 -> "Service Unavailable";
default -> "Unknown Status: " + statusCode;
};
System.out.println(message); // Not Found
計算器
double calculate(double a, String operator, double b) {
return switch (operator) {
case "+", "add" -> a + b;
case "-", "subtract" -> a - b;
case "*", "multiply" -> a * b;
case "/", "divide" -> {
if (b == 0) throw new ArithmeticException("除數不能為零");
yield a / b;
}
case "%", "mod" -> a % b;
case "^", "power" -> Math.pow(a, b);
default -> throw new IllegalArgumentException("未知運算子: " + operator);
};
}
System.out.println(calculate(10, "+", 5)); // 15.0
System.out.println(calculate(2, "^", 10)); // 1024.0
命令解析器
record Command(String action, String[] args) {}
void executeCommand(Command cmd) {
switch (cmd.action()) {
case "help" -> {
System.out.println("可用命令:");
System.out.println(" help - 顯示說明");
System.out.println(" list - 列出項目");
System.out.println(" add <item> - 新增項目");
System.out.println(" exit - 離開程式");
}
case "list" -> System.out.println("目前項目: " + Arrays.toString(cmd.args()));
case "add" -> {
if (cmd.args().length > 0) {
System.out.println("新增: " + cmd.args()[0]);
} else {
System.out.println("錯誤:請指定要新增的項目");
}
}
case "exit" -> {
System.out.println("再見!");
System.exit(0);
}
default -> System.out.println("未知命令: " + cmd.action());
}
}
版本對照
| 功能 | Java 版本 |
|---|---|
| Switch Expression (Preview) | Java 12, 13 |
| Switch Expression (正式) | Java 14 |
| yield 關鍵字 | Java 14 |
| Pattern Matching (Preview) | Java 17, 18, 19, 20 |
| Pattern Matching (正式) | Java 21 |
| null case | Java 21 |
| when 條件 | Java 21 |
重點整理
- Switch Expression 是 Java 14 引入的新語法,可以回傳值
- 使用 箭頭語法 (
->) 更簡潔,自動避免 fall-through - 多行程式碼使用
yield回傳值 - 多個 case 可用逗號合併:
case 1, 2, 3 -> - 必須處理所有可能的值(完整性檢查)
- Java 21+ 支援 Pattern Matching 和 null 處理
- 建議在 Java 14+ 專案中優先使用 Switch Expression