昨天参加农行笔试,又遇到了switch…case…,每次遇到都做不出来,真是太气人了
1、仔细阅读以下代码以及答案
代码1:
public static void main(String[] args) {
String str = "hello world!";
int len = str.length();
int val1 = 0, val2 = 0;
for(int i=0; i<len; i++) {
char c = str.charAt(i);
switch(c) {
case 'o':
val1++;
System.out.println("111::" + "c::" + c + ":::val1::" + val1);
default:
val1++;
System.out.println("222::" + "c::" + c + ":::val1::" + val1);
case 'l':
val2++;
System.out.println("333::" + "c::" + c + ":::val2::" + val1);
break;
}
System.out.println("============");
}
System.out.println("val1 is ::" + val1 + "::val2 is::" + val2);
}
答案:
222::c::h:::val1::1
333::c::h:::val2::1
============
222::c::e:::val1::2
333::c::e:::val2::2
============
333::c::l:::val2::2
============
333::c::l:::val2::2
============
111::c::o:::val1::3
222::c::o:::val1::4
333::c::o:::val2::4
============
222::c:: :::val1::5
333::c:: :::val2::5
============
222::c::w:::val1::6
333::c::w:::val2::6
============
111::c::o:::val1::7
222::c::o:::val1::8
333::c::o:::val2::8
============
222::c::r:::val1::9
333::c::r:::val2::9
============
333::c::l:::val2::9
============
222::c::d:::val1::10
333::c::d:::val2::10
============
222::c::!:::val1::11
333::c::!:::val2::11
============
val1 is ::11::val2 is::12
总结:
1)如果 case 语句块中没有 break 语句时,匹配成功后,从当前 case 开始,后续所有 case 的值都会输出,如果后续的 case 语句块中有 break 语句则会跳出判断。
2)switch case 可以包含一个 default 分支,该分支一般是 switch 语句的最后一个分支,如果是最后一个分支,则default 分支不需要 break 语句。但如果 default 分支不是最后一个分支的话,如下
代码2
public static void main(String[] args) {
int i = 3;
switch(i) {
default:
System.out.println("default:::i:::" + i);
case 1:
System.out.println("111:::i:::" + i);
case 2:
System.out.println("222:::i:::" + i);
}
}
输出结果为:
default:::i:::3
111:::i:::3
222:::i:::3
代码3:
public static void main(String[] args) {
int i = 3;
switch(i) {
default:
System.out.println("default:::i:::" + i);
case 1:
System.out.println("111:::i:::" + i);
case 2:
System.out.println("222:::i:::" + i);
case 3:
System.out.println("333:::i:::" + i);
}
}
输出结果为:
333:::i:::3
有匹配值找匹配值,没有匹配值找 default
2、switch case的底层原理
switch case 判断的条件上下顺序无关,它在内存中的实现是依靠一张表来一次存放 case 的。
switch的转换与具体系统实现有关,如果分支比较少,可能会转换为跳转指令,如果分支比较多,可能会使用跳转表。跳转表是一个映射表,存储了可能的值以及要跳转到的地址。
跳转表:其中的值必须为整数,且按照大小顺序排序(源程序中case值排序并不要求,编译器会自动排序)。按大小排序的整数可以使用高效的二分查找。
switch表达式的数据类型只能是 byte、short、int、char、枚举、String(java 7)。这是因为 switch 需要的是与整数相兼容的类型,其中 byte/short/int 本身就是整数,char 本质上也是整数(如 ‘a’ 是97),枚举类型也有对应的整数,String 用于 switch 时也会转换为整数(通过 hashCode 转换)。由于跳转表值的存储空间一般为32位,容不下Long类型,所以不能用Long。
参考自:
深入理解java之关于switch的探究
菜鸟教程