在Java中,能够进行分支控制的语句,除了if以外,还有switch。
一个switch语句由一个控制表达式和一个由case标记描述的语句块组成。
和if不同,switch后面的控制表达式求出的值应该是整型而不是boolean类型,这点在初学时要尤为注意。从控制表达式的数据类型可以看出,if语句应用范围应该更为广泛常见,因为大部分的条件分值控制都是使用真假布尔运算来判断的,这在现实世界中也极为常见,比如前面的例子,今天的计划安排,是由天气情况来决定的,下雨,不下雨,很显然就是下雨情况的真假布尔判断。
可以这么说,switch能做的事情,if完全可以做到,你在写Java代码的时候,即使你不知道switch,也可以完成代码的编写。那么switch出现的意义是什么呢?
先别急,我们先把switch的用法搞清楚了。
switch语句对控制表达式求得的值,决定了哪一个case分支将被执行。每一个case都用唯一的常量表达式或常量来标示,用于控制这个case是否必须被执行。
程序将执行到那些表达式值与控制表达式的值相匹配的case分支中。如果不存在这样的匹配,则将执行default后面的代码块。如果没有default标记(并不推荐这样做),则控制被传递到switch块后的第一条语句,也就是退出了switch块。
控制表达式必须是可以转化为byte、short、char或int类型的值的表达式。实际上switch的控制表达式接收是int类型的值,之所以能接收byte、short、char型的值,用前面提到的数据类型隐式转换就可以明白了,是Java根据实际情况,岁这几种数据类型做了类型转换,因为long不允许隐式转化为int,所以不能直接使用long型的数据值。
注意在每一个case标记的代码块中,最后都有一个break语句。这条语句具有重大的作用,如果没有这条语句,当与case分支相连续的代码块执行完毕后,将会继续运行与下一个case 分支相联系的代码块。一般情况下这与我们的初衷不符,但是有的情况下,也可以结合这种特性,简化我们的代码。看下面的这个示例:
public class SwitchCase {
public static void main(String args[]) {
int n = 2;
int result;
switch (n + 1) {
case 1: {
System.out.println("Block A");
result = n;
break;
}
case 2: {
System.out.println("Block B");
result = n * n;
break;
}
case 3: {
System.out.println("Block C");
result = n * n * n;
break;
}
case 4: {
System.out.println("Block D");
result = n % 4;
break;
}
default:
result = 0;
}
System.out.println("n=" + n + " result=" + result);
}
}
在这个例子中,定义了一个整形变量n,并给它赋值2,在switch中,根据表达式“n+1”得到的整数值执行不同的代码块:1、2、3、4都定义了各自的执行方式,如果不是这些数,则将执行default中的语句,将变量“result”赋值为0。
编译并运行上面的程序,将得到如下的结果:
Block C
n=2 result=8
从执行结果中可以很清楚的看出,case 3后面的代码被执行了,它将result赋值为n*n*n运算后得到的值,也就是为2*2*2的值。
如果一个case分支打算执行与紧随其后的case语句相同的动作,那么在这个case分支中可以不用写任何的代码:
switch(expr){
case 0:
case 1:
statements;
break;
case 2:
… …
在这里,case 0分支会执行和case 1分支一样的操作。
case相对于switch处理逻辑的入口,上面的这个示例的写法,相当于把0与1的这两个入口合并为一个逻辑了。在实际的编码情况中,这点也很常见,比如大月与小月的判断,大家可以试着写写这个判断逻辑。
最后总的来说,switch可以看做是一种特殊情况下的if语句,用来编写更加清晰,简明的分支语句,如果你的逻辑分支判断都是等值判断,并且判断的条件多于3个以上的话,switch就是更好的选择了。
if语句可以不但的嵌套,在else之后,可以继续跟进if-else语句,来完成多个复合的布尔判断分支语句。就拿遥控器操作来说,如果你按1键,进入一频道,按2键,进入2频道,按音量增大键,进行音量调节增大操作,以此类推。如果那if来写,就会出现n个if-else嵌套,无论编写,还是阅读,都难于处理维护。
比如:
if(key==1){
//操作
}else if(key==2){
//操作
}else if(key==3){
//操作
}....
else{
//操作
}
现在代码量不大,看起来还可以接受。那么如果其中的注释操作,换成真正的操作的话,这段代码量就很可观了,到时候在一对if-else中间“遨游”,你就会对这种写法痛恨不已了。
如果换成switch呢?
switch(key){
case 1:
case 2:
case 3:
...
default:
}
当然不要忘了break处理,这样看起来,即使增加了处理逻辑代码,也比if-else看起来舒服多了吧。重点是代码的可读性和可维护性,这点在实际项目中是非常重要的。