首先要了解下对于switch语句,编译器会产生两种字节码指令:tableswitch和lookupswitch。tableswitch字节码指令case的情况要是连续的值,而lookupswitch字节码指令可以case不连续的情况。如果值是不连续的话,那么每次都要遍历查找可能的情况,所以lookupswitch的效率是低于tableswitch的。
测试代码:
/**
* 编译器对switch语句的优化
*/
public class SwitchTest {
public void switchTest(int a) {
switch (a) {
case 1:
break;
case 2:
break;
case 5:
break;
}
}
}
编译后的内容以及相关的字节码文件如下:
会发现编译器对离散的数据做了填充,补上了case 3,4的情况,让他们都跳到default情况。同时该switch语句对应的字节码指令是tableswitch。
接下来把数值离散的空间拉大,如下:
/**
* 编译器对switch语句的优化
*/
public class SwitchTest {
public void switchTest(int a) {
switch (a) {
case 1:
break;
case 2:
break;
case 100:
break;
}
}
}
编译后的内容以及相关的字节码文件如下:
发现这次编译器却没有对离散的数据做填充了,因为离散的空间太大了,要插入的数据太多了,所以此时编译器选择的是效率更低的lookupswitch。
再试试不是数值,而是字符串的情况,如下:
发现编译器也会默认填充离散数据,同时该switch语句对应的字节码指令也是tableswitch。同时如果字符串的离散空间太大,如下:
对应的字节码指令就是lookupswitch了。