簡體   English   中英

什么是 switch 表達式,它們與 switch 語句有何不同?

[英]What are switch expressions and how are they different from switch statements?

作為 Java SE 12 的一部分,引入了switch表達式,並且自 Java SE 14 以來,它們已被標准化。 它們與switch語句有何不同?

switch語句:

if/else if/else語句不同, switch語句可以有許多可能的執行路徑。 switch適用於原始類型byteshortcharint 、它們各自的包裝類型( ByteShortCharacterInteger )、枚舉類型和String類型1 if-else語句用於測試基於值或條件范圍的表達式,而switch語句用於測試僅基於單個值的表達式。

演示

enum PaymentStatus {
    UNPAID, PARTPAID, PAID, DISPUTED, UNKNOWN;
}

public class Main {
    public static void main(String[] args) {
        String message = "";
        PaymentStatus paymentStatus = PaymentStatus.PARTPAID;

        switch (paymentStatus) {
        case UNPAID:
            message = "The order has not been paid yet. Please make the minimum/full amount to procced.";
            break;
        case PARTPAID:
            message = "The order is partially paid. Some features will not be available. Please check the brochure for details.";
            break;
        case PAID:
            message = "The order is fully paid. Please choose the desired items from the menu.";
            break;
        default:
            throw new IllegalStateException("Invalid payment status: " + paymentStatus);
        }
        System.out.println(message);
    }
}

Output:

The order is partially paid. Some features will not be available. Please check the brochure for details.

switch表達式:

The switch expression was introduced with Java SE 12. However, it remained as a Preview feature in Java SE 12 and 13 and finally got standardized with Java SE 14. Like any expression , switch expressions evaluate to a single value, and can be used in陳述。 它還引入了“箭頭case ”標簽,無需使用break語句來防止失敗。 從 Java SE 15 開始,支持的數據類型沒有變化(在上面的switch語句部分中提到)。

演示

enum PaymentStatus {
    UNPAID, PARTPAID, PAID, DISPUTED, UNKNOWN;
}

public class Main {
    public static void main(String[] args) {
        PaymentStatus paymentStatus = PaymentStatus.PARTPAID;

        String message = switch (paymentStatus) {
        case UNPAID -> "The order has not been paid yet. Please make the minimum/full amount to procced.";
        case PARTPAID -> "The order is partially paid. Some features will not be available. Please check the brochure for details.";
        case PAID -> "The order is fully paid. Please choose the desired items from the menu.";
        default -> throw new IllegalStateException("Invalid payment status: " + paymentStatus);
        };

        System.out.println(message);
    }
}

Output:

The order is partially paid. Some features will not be available. Please check the brochure for details.

帶有yieldswitch表達式:

從 Java SE 13 開始,您可以使用yield語句而不是箭頭運算符 (->) 從switch表達式返回值。

演示

enum PaymentStatus {
    UNPAID, PARTPAID, PAID, DISPUTED, UNKNOWN;
}

public class Main {
    public static void main(String[] args) {
        PaymentStatus paymentStatus = PaymentStatus.PARTPAID;

        String message = switch (paymentStatus) {
        case UNPAID:
            yield "The order has not been paid yet. Please make the minimum/full amount to procced.";
        case PARTPAID:
            yield "The order is partially paid. Some features will not be available. Please check the brochure for details.";
        case PAID:
            yield "The order is fully paid. Please choose the desired items from the menu.";
        default:
            throw new IllegalStateException("Invalid payment status: " + paymentStatus);
        };

        System.out.println(message);
    }
}

Output:

The order is partially paid. Some features will not be available. Please check the brochure for details.

1 JDK 7 添加了對String的支持

不錯的文案。 但我也可以為單個 case 語句添加多個 case 的功能。 下面的例子非常做作(有很多更好的方法可以實現),它對元音、數字、輔音進行了簡單的頻率計數。 和字符串中的其他字符。

int count[] = new int[4];

String s = "829s2bi9jskj*&@)(so2i2ksso";

for (char c : s.toCharArray()) {
      int i = switch (c) {
                case  'a', 'e', 'i', 'o', 'u' -> 0;
                case  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' -> 1;
                case  'b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'l',
                      'm', 'n', 'p', 'q', 'r', 's', 't', 'v', 'w',
                      'x', 'y', 'z' -> 2;
                default -> 3;
      };
      count[i]++;
}
System.out.printf("vowels  - %d%n", count[0]);
System.out.printf("digits  - %d%n", count[1]);
System.out.printf("consonants - %d%n", count[2]);
System.out.printf("other   - %d%n", count[3]);

印刷

vowels  - 4
digits  - 7
consonants - 10
other   - 5

添加到現有答案: yield也可以與->一起使用,其主要目的是允許在單個表達式不足以滿足給定情況時使用塊:

var test = switch (value) {
    case A -> 1;
    case B -> 2;
    case C -> {
        System.err.println("neither A nor B"); // or some calculation
        yield -1;
    }
}

我還要提到JEP-354 ,其中提出並描述了 switch 表達式。
可以在Java 語言規范中找到正式規范

除了上述答案之外,還可以使用 switch 表達式解決 switch 語句來查看當前的“不足”:

開關語句:

  • 問題 1:意外跌落
  • 問題 2:變量作用域
  • 問題 3:沒有返回值

開關表達式:

  • 沒有失敗
  • 組合常量
  • 屏蔽 scope
  • 回報率

例子:

開關語句:

private static void oldSwitchStatement(String month) {

    int i = 0;
    String quarter = "";

    switch (month) {
        case "JAN":
        case "FEB":
        case "MAR":
            i = i + 1;
            quarter = "Q1";
            // break;
        case "APR":
        case "MAY":
        case "JUN":
            i = i + 2;
            quarter = "Q2";
            // break;
        case "JUL":
        case "AUG":
        case "SEP":
            i = i + 3;
            quarter = "Q3";
            // break;
        case "OCT":
        case "NOV":
        case "DEC":
            i = i + 4;
            quarter = "Q4";
        default:
            System.out.println("Unknown case");
    }

    System.out.println("QUARTER: "+ i + " "+ quarter);
}

切換表達式

private static String newSwitchExpressionYield(String month) {

    return switch (month) {
        case "JAN", "FEB", "MAR" -> "Q1";
        case "APR", "MAY", "JUN" -> {
            System.out.println("Using yield.");
            yield "Q2";
        }
        case "JUL", "AUG", "SEP" -> "Q3";
        case "OCT", "NOV", "DEC" -> "Q4";
        default -> "Unknown case";
    };
}

要測試以上通過oldSwitchStatement("APR"); newSwitchExpressionYield("APR"); 並查看結果。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM