01_basic_09_switch_statement

第九章 switch语句

1 简介

当Java程序出现多重分支时,可以考虑使用switch语句。switch语句会根据条件表达式的计算结果来决定哪些分支会被执行。下面是一种常见的switch语句的使用方法示例。switch是Java语言的关键字,用于表示这是一条switch语句。在关键字switch之后紧跟着的是一个表达式。这个表达式放置在一对括号之中。在这个例子中,这个表达式生成一个int类型的值。

在switch语句中,每个分支是由关键字case,一个常量,一个冒号和一组语句组成。当这个常量的值与上述表达式的结果相同时,这条分支语句会被执行。例如,在下面的示例中,因为x%2的值为1。所以,case 1分支中的语句会被执行。程序会打印“这是一个奇数”。

我们常常会将switch语句的最后一个分支设置为默认分支,使用关键字default标识。这是一个良好的编程习惯;默认分支用于处理哪些无法找到匹配分支运行的情况。

int x = 1;
switch (x % 2) 
{
    case 0:
        System.out.println("这是一个偶数");
        break;
    case 1:
        System.out.println("这是一个奇数");
        break;
    default:
        System.out.println("不可能执行到这里");
        break;
}

我们从上面的例子中可以看出,虽然每个分支都存在两条语句,但是它们不需要使用花括号组成一个代码块。在每个分支中都使用了break语句,用于跳出switch语句。因为,如果不使用break语句的话,switch语句会按照分支出现的顺序,继续往下执行。我们称这个特性为fall through。因此,在下面的示例中,当表达式x%3的结果为1或者2时,程序都会打印"这不是3的整数倍"。这是因为当表达式的值为1时,它会fall through到case 2的分支继续执行。

int x = 1;
switch (x % 3)
{
    case 0:
        System.out.println("这是3的整数倍");
        break;
    case 1: // fall through
    case 2:
        System.out.println("这不是3的整数倍");
        break;
    default:
        System.out.println("不可能执行到这里");
        break;
}

如果当两个分支需要执行相同代码时,我们可以把这两个分支合并(Java 14及以上版本支持)。

int x = 50;
switch (x % 3)
{
    case 0:
        System.out.println("这是3的整数倍");
        break;
    case 1, 2: // 两个分支合并(Java 14及以上版本支持)
        System.out.println("这不是3的整数倍");
        break;
    default:
        System.out.println("不可能执行到这里");
        break;
}

2 switch语句的另一种结构

使用关键字case和冒号标识分支是一种常见的switch语句的结构,我们称之为Switch Labeled Statement Group。但是,Java语言还支持另一种形式来表示分支,我们称之为Switch Rule (Java 14及以上版本支持)。

其实这两种形式非常相似。第二种形式使用->取代了冒号。与第一种方式不同的是,Switch Rule分支不支持fall through特性。所以,当使用Switch Rule时,每个分支中不需要使用break语句。在每个rule执行完毕后,会自动跳出switch语句。

// Java 14及以上版本支持
int x = 1;
switch (x % 2) 
{
    case 0 -> System.out.println("这是一个偶数");
    case 1 -> System.out.println("这是一个奇数");
    default -> System.out.println("不可能执行到这里");
}

3 使用枚举类型

在实际应用中,枚举类型常常会被用来做分支判断。例如,假如我们定义了一个枚举类型Day来表示工作日和周末。

enum Day {
    WORKDAY,  // 工作日
    WEEKEND;  // 周末
}

那么,我们可以通过比较枚举的值来做分支判断。

Day today = Day.WEEKEND;
switch (today)
{
    case WORKDAY:
        System.out.println("今天是工作日。");
        break;
    case WEEKEND:
        System.out.println("今天是周末。");
        break;
    default:
        System.out.println("Can't be here");
        break;
}

4 使用字符串类型

字符串也是一种常用于分支判断的类型。当然,switch语句也支持字符串比较,来决定分支。例如,在下面的示例中,我们使用了字符串变量today来和字符串字面常量"Workday"和"Weekend"比较,以决定执行分支。

String today = "Weekend";
switch (today)
{
    case "Workday":
        System.out.println("今天是工作日。");
        break;
    case "Weekend":
        System.out.println("今天是周末。");
        break;
    default:
        System.out.println("Can't be here");
        break;
}

5 yield语句(yield statement)

在Java 14版本中,Java语言添加了yield语句。yield语句只能用在switch表达式中。在这里,我们称之为switch表达式,而不是称之为switch语句是因为这个switch表达式并不能独立的称为一条语句。因为yield语句会为这个switch表达式生成一个值。

yield语句有两个功能。其一,为所在的switch表达式生成一个值。如果yield语句执行成功,那么可以认为所在的switch表达式执行成功。其二,yield语句改变了执行顺序。在yield语句执行之后,程序将结束当前switch语句的执行。

我们使用下面的一个示例来介绍yield语句的使用方法。首先,在getMessageByDay()方法中,唯一的一条语句是return语句。switch表达式是作为return语句的参数加入的。第二,switch表达式中的分支并没有使用break语句来跳出switch表达式,而是使用了yield语句来结束switch表达式的执行。第三,yield语句为switch表达式生成了一个值,可用于传入return语句中。

public class YieldStatementExample {
    enum Day {
      WORKDAY,  // 工作日
      WEEKEND;  // 周末
    }

    public static String getMessageByDay(Day today) {
        return switch (today)
            {
                case WORKDAY:
                    yield "今天是工作日。";
                case WEEKEND:
                    yield "今天是周末。";
                default:
                    yield "Can't be here";
            };
    }
}

6 小结

switch语句是一条多分支的语句。它支持在一条语句中指定多条不同的执行分支。switch语句的运行逻辑不难理解,但是,值得注意的是,switch语句支持fall through特性。小水滴建议开发人员在使用fall through特性时明确注明其使用目的,以增强代码的可读性。

上一章
下一章

注册用户登陆后可留言

Copyright  2019 Little Waterdrop, LLC. All Rights Reserved.