传统 switch 语句
传统的 switch
语句我们已经写了一万遍了,以下是一个典型的 switch
语句:
int dayOfWeek = 3;
switch (dayOfWeek) {
case 1:
System.out.println("星期一");
break;
case 2:
System.out.println("星期二");
break;
case 3:
System.out.println("星期三");
break;
case 4:
System.out.println("星期四");
break;
case 5:
System.out.println("星期五");
break;
case 6:
System.out.println("星期六");
break;
case 7:
System.out.println("星期日");
break;
default:
System.out.println("星期???");
break;
}
众所周知啊,写 switch
语句最重要的就是不能忘了 break
语句,这主要是 switch
的穿透机制。即 switch
结构在找到第一个匹配的 case
条件后,会顺序执行后面所有 case
对应的代码,无论是否判断为真,知道碰到 break
跳出。你可以看看上面写了多少个 break
。
这是40多年前 C 语言创造后,Java 原样照抄的经典语法,但在今天看来就老套和啰嗦了。
除去由穿透机制带来的大量 break
造成的代码冗余、可读性不好等缺点,这种传统的 switch
语句还有变量作用域混乱的问题。例如如下的代码是不能通过编译的:
switch (today) {
case MODAY:
int x = 1;
break;
default:
int x = 0; //Variable x is already defined in the scope
}
Java 12 的 switch 语句 和 switch 表达式
由于上面的问题,Java 12 对 switch
语句进行了改造,使得语句变得更简洁清晰了。就像上面的传统 switch
语句,现在可以这么写了:
int dayOfWeek = 3;
switch (dayOfWeek) {
case 1 -> System.out.print("星期一");
case 2 -> System.out.print("星期二");
case 3 -> System.out.print("星期三");
case 4 -> System.out.print("星期四");
case 5 -> System.out.print("星期五");
case 6 -> System.out.print("星期六");
case 7 -> System.out.print("星期日");
default -> System.out.println("星期???");
}
这种写法在 case
之后使用 ->
符号,可以只执行之后的语句,不需要添加 break
关键字,没有穿透效应。但是如果后面跟多条语句,需要用大括号 { }
括起来。
这是 switch
作为普通语句(statement)来使用的,Java 12 之后,switch
还可以作为表达式(expression)来使用的。也就是说,从 Java 12 之后,switch
是可以有返回值的。
之前我们使用 switch
为变量赋值都是这样的:
String word; //通过 switch 为此变量赋值
int dayOfWeek = 3;
switch(dayOfWeek) {
case 1 :
word = "星期一";
break;
case 2:
word = "星期二";
break;
case 3:
word = "星期三";
break;
default:
word = "星期---";
break;
}
现在使用 Java 12 的 switch
表达式,我们就可以将上面的代码改写为:
int dayOfWeek = 3;
String word = switch(dayOfWeek) {
case 1 -> "星期一";
case 2 -> "星期二";
case 3 -> "星期三";
default -> "星期---";
}; //主要此处要有分号
需要注意的是当 switch
作为表达式时,需要在 switch
结构后面加上分号。而且,当 switch
作为表达式使用时,每一个分支(case
、break
)都必须有返回值(或者抛出异常)。
这里插播一下我的公众号,希望大家多多关注,以后我会发更多的高质量内容:
yield 关键字
大多数时候,在 switch
表达式内部,我们会返回简单的值,这个时候就像上面一样将返回的值写在 ->
之后就行。但是,如果需要复杂的语句,例如写了很多语句放到 { }
中,那么此时,如何在此分支中返回一个值呢?这就需要用到 yield
关键字。
例如上面的代码我们可以改成这样:
int dayOfWeek = 3;
String word = switch(dayOfWeek) {
case 1 -> "星期一";
case 2 -> "星期二";
case 3 -> "星期三";
default -> {
String result = "星期---";
//do a lot of work.
yield result; //通过 yield 返回一个值
}
};
在上面的 default
分支中,写了几行代码,并在最后用 yield
返回了这个值。