1、switch中是int类型的
代码:
public class Test {
public void hello(int a) {
switch (a) {
case 100:
System.out.println(100);
break;
case 300:
System.out.println(200);
break;
case 200:
System.out.println(300);
break;
default:
System.out.println(400);
}
}
}
解释:
直接看字节码文件,如下所示:
0 iload_1
1 lookupswitch 3
100: 36 (+35)
200: 59 (+58)
300: 47 (+46)
default: 71 (+70)
……
虽然我们写的时候是先写100,在写300,然后在写200,但是判断的时候是先判断100,其次是200,最后是300,字节码文件里面对相应的case情况会自动排序,所以我们写java代码的时候最好也是按照先后顺序写
另外我还想说的一点是如果几个数字是连续的,那么查找起来就更方便了,比如我们将上面的情况变成101、102、103,那么字节码文件如下图:
0 iload_1
1 tableswitch 100 to 102 100: 28 (+27)
101: 39 (+38)
102: 51 (+50)
default: 63 (+62)
……
可以看到范围是100到102,字节码执行的时候会先判断和第1个排序之后的case相等吗,如果不相等,那就可以根据该数值和第1个case数值得出该数值到底在那个位置,进而调到对应的位置执行代码,这样来做的话效率更高
2、switch中是String类型的
代码:
public class Test {
public void hello(String str) {
switch (str) {
case "java":
System.out.println("java");
break;
case "python":
System.out.println("python");
break;
case "go":
System.out.println("go");
break;
default:
System.out.println("c");
}
}
}
解释:
直接来看字节码文件吧,如下所示:
0 aload_1
1 astore_2
2 iconst_m1
3 istore_3
4 aload_2
5 invokevirtual #2 <java/lang/String.hashCode>
8 lookupswitch 3
-973197092: 58 (+50)
3304: 72 (+64)
3254818: 44 (+36)
default: 83 (+75)
……
里面lookupswitch
下面的那些数值是对应case情况中字符串中的哈希码值,这种比较方式相比于直接使用equals方法
比较成本更低一点,如果出现哈希冲突,字节码中也有对应的方式去应对,因为字节码中还会使用equals方法
再次进行判断的