1. switch 有哪些新功能
如果你在 Java 14 之前寫過程式,switch 大致上是這樣的:
switch (day)
{
case MONDAY:
System.out.println("一週的開始!");
break;
case FRIDAY:
System.out.println("星期五,耶!");
break;
default:
System.out.println("平常的一天。");
break;
}
看起來沒什麼問題,但:
- 必須記得 break(否則會「落入」下一個 case)。
- 有很多重複的程式碼。
- 如果想要回傳值,就得事先宣告一個變數,並在每個 case 內賦值。
Java 14+ 說:夠了!該讓 switch 更方便、現代化了。
主要新增點:
- switch 成為表達式,不再只是語句——現在可以回傳值。
- 使用新的箭頭語法 ->,取代冒號與 break。
- 多個 case 可用逗號串接,以共用相同邏輯。
- 編譯器會檢查是否覆蓋所有分支(特別是搭配 enum)。
- 不會再意外「落入」(fall-through)——只有在你明確允許時才會發生。
2. switch 表達式的語法
switch (znachenie)
{
case A, B -> rezultat1;
case C -> {
// 多個動作
yield rezultat2;
}
default -> rezultatPoUmolchaniyu;
}
使用
-> 與
yield 的 switch 表達式語法
基本範例
直接看重點。以下示範如何從 switch 回傳值:
DayOfWeek day = DayOfWeek.MONDAY;
String message = switch (day)
{
case MONDAY, FRIDAY, SUNDAY -> "短週或是假日!";
case TUESDAY -> "星期二—辛苦的一天。";
case WEDNESDAY, THURSDAY -> "週中!";
case SATURDAY -> "耶,星期六!";
// 如果不是所有分支都已處理,必須要有 default
default -> "有點奇怪的一天……";
};
System.out.println(message);
重點說明:
- switch (day) 是會回傳值的表達式。
- 箭頭 -> 後面就是該 case 的結果。
- 多個 case 可以用逗號合併。
- 完全不需要 break——Java 會自動在分支結束處收尾。
- 可以直接把結果指定給變數 message。
數值範例
int code = 404;
String result = switch (code)
{
case 200 -> "OK";
case 400, 404 -> "用戶端錯誤";
case 500 -> "伺服器錯誤";
default -> "未知代碼";
};
System.out.println(result);
字串範例
String command = "start";
String status = switch (command)
{
case "start" -> "啟動!";
case "stop" -> "停止!";
case "pause" -> "暫停……";
default -> "未知指令";
};
System.out.println(status);
搭配 yield 的區塊用法
有時候希望在同一個 case 裡執行多個動作(例如先做較複雜的計算或記錄 log)。此時可使用區塊 { ... } 與關鍵字 yield:
int n = 7;
String parity = switch (n % 2)
{
case 0 -> "偶數";
case 1 ->
{
System.out.println("偵測到奇數: " + n);
yield "奇數";
}
default -> "有點奇怪";
};
System.out.println(parity);
重要:在區塊中一定要有 yield,它會回傳該 case 的值。
3. 新語法的優點
不再需要 break
在傳統的 switch 中,少寫一個 break 就是痛苦與詭異 bug 的來源。新語法中完全不需要 break:每個分支都會自動結束。
編譯器會檢查是否涵蓋所有分支
如果你使用 enum 卻沒有處理所有值——沒有 default 就無法編譯。這讓程式更可靠。
不會「落入」(fall-through)
在傳統的 switch 中,若忘了 break,執行流程會「落入」下一個 case。在新語法中這不會發生(除非你在區塊中明確寫出指令與 break——但在這裡並不需要)。
程式碼更精簡、可讀性更高
自行比較:
以前:
String result;
switch (status) {
case "OK":
result = "一切都好";
break;
case "ERROR":
result = "錯誤";
break;
default:
result = "未知";
break;
}
之後:
String result = switch (status) {
case "OK" -> "一切都好";
case "ERROR" -> "錯誤";
default -> "未知";
};
多個 case——一套邏輯
case MONDAY, FRIDAY, SUNDAY -> "假日或短工時的一天!";
4. 與傳統 switch 的比較
| 特性 | 傳統 switch | 新式 switch |
|---|---|---|
| 必須寫 break | 是 | 否 |
| 落入(fall-through) | 是 | 否 |
| 可否回傳值 | 否(只能透過變數) | 是(表達式) |
| 多個 case 以逗號分隔 | 否 | 是 |
| 檢查是否涵蓋所有分支 | 否 | 是(特別是搭配 enum) |
| 精簡程度 | 大量程式碼 | 簡短明瞭 |
| 是否支援 enum 與字串 | 是 | 是 |
5. 與 enum 與字串的相容性
搭配 enum 的範例
假設我們有一個列舉:
enum DayOfWeek
{
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
在新的 switch 中使用它:
DayOfWeek today = DayOfWeek.WEDNESDAY;
String mood = switch (today)
{
case MONDAY -> "起床好痛苦……";
case FRIDAY -> "快放假了!";
case SATURDAY, SUNDAY -> "耶,休息!";
default -> "工作日。";
};
System.out.println(mood);
搭配 String 的範例
String season = "summer";
String activity = switch (season)
{
case "winter" -> "溜冰";
case "summer" -> "在湖裡游泳";
case "autumn" -> "採蘑菇";
case "spring" -> "聽鳥鳴";
default -> "未知的季節";
};
System.out.println(activity);
6. 把舊式 switch 重寫為新風格
原本:
int day = 3;
String dayName;
switch (day)
{
case 1:
dayName = "星期一";
break;
case 2:
dayName = "星期二";
break;
case 3:
dayName = "星期三";
break;
default:
dayName = "未知的日子";
break;
}
System.out.println(dayName);
改成:
int day = 3;
String dayName = switch (day)
{
case 1 -> "星期一";
case 2 -> "星期二";
case 3 -> "星期三";
default -> "未知的日子";
};
System.out.println(dayName);
再一個例子:多個 case——一套邏輯
int score = 5;
String grade = switch (score)
{
case 5, 6, 7 -> "良好";
case 8, 9, 10 -> "優秀";
default -> "需要再努力";
};
System.out.println(grade);
7. 常見錯誤與注意事項
錯誤一:未覆蓋所有分支卻缺少 default。 若使用的 switch 表達式之型別可能出現未列在 case 中的值(例如 int 或 String),編譯器會要求 default。對 enum 而言,若未處理所有值,也必須提供 default。
錯誤二:在區塊中忘記寫 yield。 若在 case 中使用大括號(需要執行多個動作),別忘了 yield——否則編譯器會報錯:"Missing yield statement"。
錯誤三:型別不一致。 switch 表達式的所有分支都必須回傳相同型別的值;否則編譯不會通過。
錯誤四:重複的 case 值。 同一個 case 不能出現兩次——編譯器會直接報錯。
GO TO FULL VERSION