軌道
/
Java
Java
/
課程大綱
/
`switch` 敘述
`s

`switch` 敘述 在 Java

2 個練習

關於 `switch` 敘述

就像 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 實作。

  1. 你可以在單一 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;
        // (...)
    }
    
  2. 你現在可以寫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。

  3. switch statements 與 switch expressions 的另一個差別是:在 switch expressions 中,你_必須_涵蓋所有情況。 做法是為所有可能的值都加上case,或是使用default case。

  4. 你可以用->取代:。 使用->時可以不寫break關鍵字。 兩種寫法都可以用,但在同一個 switch 裡只能固定用其中一種。

     switch(expression) {
         case 1 -> yield "one"
         case 2 -> yield "two"
         default: yield "other number" // Removing this will result in a compile error
     }
    
  5. 作用域。 傳統的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 運算式的資訊。

透過 GitHub 編輯 連結會在新視窗或分頁中開啟

學習 `switch` 敘述