写在前面:初中肄业文化水平,如有不足欢迎指正。
switch语句作为一种选择语句,也被称为开关语句,实际开发时由于自己能力问题很少选择该语句作为方案。相比ifelse语句,switch无疑在逻辑展示方面更加的清晰,如果遇到固定值的多重判断时,switch应该是大多情况的首选方案。
switch(表达式){
case 值1:
代码块1;
break;
case 值2:
代码块2;
break;
case 值3:
代码块3;
break;
...........
default:
默认执行;
}
1.switch根据不同的情况会有不同的格式变化,首先是最常见的贯穿:
public class DemoSwithCase {
public static void main(String[] args) {
int 贯穿数字 = 7;
switch (贯穿数字){
case 7:
贯穿数字++;//执行自增 7-》8
case 8:
贯穿数字++;//执行自增 8-》9
case 9:
贯穿数字++;//执行自增 9-》10
default:
System.out.println(贯穿数字);// result:10
}
}
}
2.switch在JDK1.7(老年人了,叫的正规见谅)以后可以判断String类型的对象了
1 public static void main(String[] args) {
2 String area = "China";
3 switch (area){
4 case "China":
5 System.out.println("China!");//输出:China!
6 break;
7 case "Japan":
8 System.out.println("Japan!");
9 break;
10 case "English":
11 System.out.println("English!");
12 break;
13 default:
14 System.out.println("钓鱼岛是中国的!");
15 break;
16 }
17 }
但是这样做判断有一个明确的规定就是case和小括号里面不能写null;
好奇宝宝就想知道为什么在这两处不能写null,于是试着用idea的jclasslib插件查看字节码详情
0 ldc #2 <China> //int取值
2 astore_1 //出栈 赋值给局部变量表对应数组下标为1的元素
3 aload_1 //进栈 当前局部变量表对应数组下标为1的元素
4 astore_2 //出栈
5 iconst_m1 //int 常量值-1进栈
6 istore_3
7 aload_2
8 invokevirtual #3 <java/lang/String.hashCode> //调用引用类型的方法的引用 这里调用了String.hashCode方法
11 lookupswitch 3 //switch语句对应字节码:备用开关,非紧凑情况使用,带键值标签
60895824: 72 (+61) //这里就可以看到String类型实际在JVM执行时是采用hashcode值比较的
65078583: 44 (+33)
71341030: 58 (+47)
default: 83 (+72)
44 aload_2
45 ldc #2 <China>
47 invokevirtual #4 <java/lang/String.equals>
50 ifeq 83 (+33)
53 iconst_0
54 istore_3
55 goto 83 (+28)
58 aload_2
59 ldc #5 <Japan>
61 invokevirtual #4 <java/lang/String.equals>
64 ifeq 83 (+19)
67 iconst_1
68 istore_3
69 goto 83 (+14)
72 aload_2
73 ldc #6 <English>
75 invokevirtual #4 <java/lang/String.equals>
78 ifeq 83 (+5)
81 iconst_2
82 istore_3
83 iload_3
84 tableswitch 0 to 2 0: 112 (+28)
1: 123 (+39)
2: 134 (+50)
default: 145 (+61)
112 getstatic #7 <java/lang/System.out>
115 ldc #8 <China!>
117 invokevirtual #9 <java/io/PrintStream.println>
120 goto 153 (+33)
123 getstatic #7 <java/lang/System.out>
126 ldc #10 <Japan!>
128 invokevirtual #9 <java/io/PrintStream.println>
131 goto 153 (+22)
134 getstatic #7 <java/lang/System.out>
137 ldc #11 <English!>
139 invokevirtual #9 <java/io/PrintStream.println>
142 goto 153 (+11)
145 getstatic #7 <java/lang/System.out>
148 ldc #12 <钓鱼岛是中国的!>
150 invokevirtual #9 <java/io/PrintStream.println>
153 return
从上面的字节码大致可以分析到一些结果,首先switch语句在JVM执行时无论判断的对象是什么类型,最后都会转变为以一个int类型的数值来比较,并返回比较结果。
那么当String的对象为null时,该对象不存在对应的hashCode值,也就无法作为equals的比较中的任何一方,最后导致空指针异常。
并且由于在JVM解析switch语句时会首先获得判断对象的hashCode值,所以在这个时候异常就出现了。
String area = null;
switch (area){//NullPointerException
case "China":
System.out.println("China!");//输出:China!
break;
case "Japan":
System.out.println("Japan!");
break;
case "English":
System.out.println("English!");
break;
default:
System.out.println("钓鱼岛是中国的!");
break;
}
以上就是好奇宝宝的第一次探险经历总结。不得不说,java还是有很多细节和特性等待宝宝去慢慢挖掘der。