就像 if/else 敘述一樣,switch敘述可以讓你透過有條件地執行程式碼,改變程式的流程。
差別在於,switch敘述只能把基本型別或字串運算式的值,與事先定義好的常數值做比較。
使用 switch 敘述時,有些關鍵字很有用。
switch:這個關鍵字用來宣告 switch 的結構。
後面接著會讓結果改變的運算式或變數。case:用它來宣告結果各種可能的情況。break:break關鍵字非常有用,可以在想要的分支結束時停止 switch 的執行。
如果忘記寫,程式會繼續執行,可能導致非預期的結果。default:顧名思義,當沒有其他 case 符合運算式的結果時,用它作為預設結果。最基本的形式,是測試一個基本型別或字串運算式,並根據它的值做出決定。 例如:
String direction = getDirection();
switch (direction) {
case "left":
goLeft();
break;
case "right":
goRight();
break;
default:
// otherwise
markTime();
break;
}
從 Java 14 開始(先前在 Java 12 和 13 中可作為預覽功能提供),已經可以使用「增強版」的 switch 實作。
你可以在單一 case 中指派多個值。
在傳統的 switch 敘述裡,你可以使用 fall-through。在下面的例子中,case 1和case 3會執行相同的內容。
這是因為case 1沒有使用break關鍵字。
switch (number) {
case 1:
case 3:
// do same stuff
break;
case 2:
// do different stuff
break;
// (...)
}
在增強的switch expression中,你可以直接把多個值指派給一個case。
請看下面的例子:
switch (number) {
case 1, 3:
// do stuff
break;
case 2:
// do other stuff
break;
// (...)
}
你現在可以寫switch-statement或switch expression。
差別在哪裡?
基本上,敘述講求的是嚴謹的邏輯,而運算式可以回傳值。
與其這樣寫:
String result = "";
switch (expression) {
case "bob":
result = "bob";
break;
// (...)
}
你可以這樣寫:
String result = switch (expression) {
case "bob":
yield "bob";
// (...)
}
yield的作用類似return,只是它是用在 switch 運算式上。
由於yield會終止運算式,這裡不需要break。
switch statements 與 switch expressions 的另一個差別是:在 switch expressions 中,你_必須_涵蓋所有情況。
做法是為所有可能的值都加上case,或是使用default case。
你可以用->取代:。
使用->時可以不寫break關鍵字。
兩種寫法都可以用,但在同一個 switch 裡只能固定用其中一種。
switch(expression) {
case 1 -> yield "one"
case 2 -> yield "two"
default: yield "other number" // Removing this will result in a compile error
}
作用域。
傳統的switch因為作用域的關係,可能導致一些非預期的行為,因為整個switch只有一個作用域。
switch(expression) {
case 1:
String message = "something";
break;
case 2:
String message = "anything";
break;
// (...)
}
這個例子無法運作,因為 message 在switch裡被宣告了兩次。
可以這樣解決:
switch (expression) {
case 1: {
String message = "something";
break;
}
case 2: {
String message = "anything";
break;
}
// (...)
}
因為{}界定了case的作用域。
不過這並不直覺,因為{}並非必要。
但如果你使用新的->寫法,它後面必須接其中一種:單一敘述或運算式、throw敘述,或是{}區塊。
不會再搞混了!
你可以在這篇文章和這一篇找到更多關於增強版 switch 的資訊,還有官方的 Oracle 文件。
此外,Java 21 新增了一項稱為Guarded Patterns的功能,讓你可以直接在 case 標籤裡做檢查。
String dayOfMonth = getDayOfMonth();
String day = "";
return switch (day) {
case "Tuesday" when dayOfMonth == 13 -> "Forbidden day!!";
case "Monday", "Tuesday", "Wednesday", "Thursday", "Friday" -> "Week day";
case "Saturday", "Sunday" -> "Weekend";
default -> "Unknown";
};
你可以在這篇部落格找到更多關於 Java 21 中 switch 運算式的資訊。