传统 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
返回了这个值。