系列中的上一篇
当前教程
使用 Switch 语句进行分支
系列中的下一篇

系列中的上一篇: 控制流语句

系列中的下一篇: 使用 Switch 表达式进行分支

使用 Switch 语句进行分支

 

使用 Switch 语句控制程序流程

switch 语句是 Java 语言中五种控制流语句之一。它允许使用任意数量的执行路径。switch 语句以选择器变量作为参数,并使用该变量的值来选择将要执行的路径。

您必须从以下类型中选择选择器变量的类型

  • byteshortcharint 原生数据类型
  • CharacterByteShortInteger 包装类型
  • 枚举类型
  • String 类型。

值得注意的是,以下原生类型不能用作选择器变量的类型: booleanlongfloatdouble

让我们看一个 switch 语句的第一个示例。

int quarter = ...; // any value

String quarterLabel = null;
switch (quarter) {
    case 0: quarterLabel = "Q1 - Winter"; 
            break;
    case 1: quarterLabel = "Q2 - Spring"; 
            break;
    case 2: quarterLabel = "Q3 - Summer"; 
            break;
    case 3: quarterLabel = "Q3 - Summer"; 
            break;
    default: quarterLabel = "Unknown quarter";
};

switch 语句的主体称为 switch 块。switch 块中的语句可以用一个或多个 casedefault 标签标记。switch 语句评估其表达式,然后执行所有在匹配的 case 标签之后出现的语句。

您可能已经注意到 break 关键字的使用。每个 break 语句都会终止封闭的 switch 语句。控制流将从 switch 块之后的第一个语句继续。break 语句是必要的,因为如果没有它们,switch 块中的语句就会贯穿。所有在匹配的 case 标签之后的语句都会按顺序执行,而不管后续 case 标签的表达式如何,直到遇到 break 语句。

以下代码使用贯穿来填充 futureMonths 列表。

int month = 8;
List<String> futureMonths = new ArrayList<>();

switch (month) {
    case 1:  futureMonths.add("January");
    case 2:  futureMonths.add("February");
    case 3:  futureMonths.add("March");
    case 4:  futureMonths.add("April");
    case 5:  futureMonths.add("May");
    case 6:  futureMonths.add("June");
    case 7:  futureMonths.add("July");
    case 8:  futureMonths.add("August");
    case 9:  futureMonths.add("September");
    case 10: futureMonths.add("October");
    case 11: futureMonths.add("November");
    case 12: futureMonths.add("December");
             break;
    default: break;
}

从技术上讲,最后的 break 不是必需的,因为流程会从 switch 语句中退出。建议使用 break,这样修改代码更容易,错误也更少。

default 部分处理所有未被任何 case 部分显式处理的值。

以下代码示例展示了如何让一个语句具有多个 case 标签。代码示例计算特定月份的天数

int month = 2;
int year = 2021;
int numDays = 0;

switch (month) {
    case 1: case 3: case 5:   // January March May
    case 7: case 8: case 10:  // July August October
    case 12:
        numDays = 31;
        break;
    case 4: case 6:   // April June
    case 9: case 11:  // September November
        numDays = 30;
        break;
    case 2: // February
        if (((year % 4 == 0) && 
             !(year % 100 == 0))
             || (year % 400 == 0))
            numDays = 29;
        else
            numDays = 28;
        break;
    default:
        System.out.println("Invalid month.");
        break;
}

此代码对多个 case 只有一个语句。

 

在 Switch 语句和 If-then-else 语句之间进行选择

决定是使用 if-then-else 语句还是 switch 语句取决于可读性和语句正在测试的表达式。if-then-else 语句可以测试基于值范围或条件的表达式,而 switch 语句只能测试基于单个整数、枚举值或 String 对象的表达式。

例如,以下代码可以使用 switch 语句编写。

int month = ...; // any month
if (month == 1) {
    System.out.println("January");
} else if (month == 2) {
    System.out.println("February");
} ... // and so on

另一方面,以下代码不能使用 switch 语句编写,因为 switch 语句不支持类型为 boolean 的标签。

int temperature = ...; // any temperature
if (temperature < 0) {
    System.out.println("Water is ice");
} else if (temperature < 100){
    System.out.println("Water is liquid, known as water");
} else {
    System.out.println("Water is vapor");
}

 

使用 String 作为 Case 标签的类型

在 Java SE 7 及更高版本中,您可以在 switch 语句的表达式中使用 String 对象。以下代码示例根据名为 month 的 String 的值显示月份的编号。

String month = ...; // any month
int monthNumber = -1;

switch (month.toLowerCase()) {
    case "january":
        monthNumber = 1;
        break;
    case "february":
        monthNumber = 2;
        break;
    case "march":
        monthNumber = 3;
        break;
    case "april":
        monthNumber = 4;
        break;
    case "may":
        monthNumber = 5;
        break;
    case "june":
        monthNumber = 6;
        break;
    case "july":
        monthNumber = 7;
        break;
    case "august":
        monthNumber = 8;
        break;
    case "september":
        monthNumber = 9;
        break;
    case "october":
        monthNumber = 10;
        break;
    case "november":
        monthNumber = 11;
        break;
    case "december":
        monthNumber = 12;
        break;
    default: 
        monthNumber = 0;
        break;
}

switch 表达式中的 String 与与每个 case 标签关联的表达式进行比较,就好像正在使用 String.equals() 方法一样。为了让此示例接受任何月份,无论大小写如何,month 都被转换为小写(使用 toLowerCase() 方法),并且与 case 标签关联的所有字符串都为小写。

 

空选择器变量

switch 语句的选择器变量可以是对象,因此该对象可以为空。您应该保护您的代码免受空选择器变量的影响,因为在这种情况下,switch 语句将抛出 NullPointerException


上次更新: 2021 年 9 月 14 日


系列中的上一篇
当前教程
使用 Switch 语句进行分支
系列中的下一篇

系列中的上一篇: 控制流语句

系列中的下一篇: 使用 Switch 表达式进行分支