Switch语法switch作为Java内置关键字 , 却在项目中真正使用的比较少 。关于switch,还是有那么一些奥秘的 。
要什么switch,我有if-else确实,项目中使用switch比较少的一个主要原因就在于它的作用能被if-else代替,况且switch对类型的限制,也阻碍了switch的进一步使用 。
先看看switch的语法:
switch(exp){case exp1:break;case exp2:break;default:break;}其中exp的类型限制为:byte ,short , int , char,及其包装类 , 以及枚举和String(JDK1.7)
为什么要有这些限制?如果说,switch的功能和if-else的一模一样,那么它存在的意义在哪里?
答案是:switch和if-else在设计的时候 , 是有一定的性能差别的 。
看代码:
public class Test {public static void switchTest(int a) {switch (a) {case 1:System.out.println("1");break;case 2:System.out.println("2");break;default:System.out.println("3");break;}}}javap  -c Test.class 结果如下:public static void switchTest(int);Code:0: iload_01: lookupswitch{ // 21: 282: 39default: 50} ...这里面省略一些代码 。
可以发现,switch是通过lookupswitch指令实现 。那么lookupswitch指令是干嘛的呢?
在Java se8文档中的描述可以大概知道:
switch可以被编译为两种指令
lookupswitch:当switch的case比较稀疏的时候,使用该指令对int值的case进行一一比较 , 直至找到对应的case(这里的查找,可以优化为二分查找)tableswitch:当switch的case比较密集的时候,使用case的值作为switch的下标,可以在时间复杂度为O(1)的情况下找到对应的case(可以类比HashMap)
现在,我们应该能够明白,为什么The Java Virtual Machine's tableswitch and lookupswitch instructions operate only on int data. Because operations on byte, char, or short values are internally promoted to int, a switch whose expression evaluates to one of those types is compiled as though it evaluated to type int. If the chooseNear method had been written using type short, the same Java Virtual Machine instructions would have been generated as when using type int. Other numeric types must be narrowed to type int for use in a switch.
大概翻译如下:Java虚拟机的tableswitch和lookupswitch指令仅对int数据进行操作 。因为对byte、char或short值的操作在内部被提升为int, 所以其表达式计算为这些类型之一的switch被编译为好像它计算为int类型 。如果使用short类型编写了chooseNear方法,则将生成与使用int类型时相同的Java虚拟机指令 。其他数字类型要在switch中使用必须转为int类型 。
switch关键字会有类型限制了 , 因为 switch所被翻译的关键字是被限制为int类型的,至于为什么是int,我猜应该是基于性能和实现的复杂度的考量吧 。int之外的类型我们明白了
byte,shor,char,int能被作为switch类型后 , 再看看枚举和Stringpublic static void switchTest(String a) {switch (a) {case "1":System.out.println("1");break;case "2":System.out.println("2");break;default:System.out.println("3");break;}}编译生成
Test.class 。拖入IDEA进行反编译得到如下代码:public static void switchTest(String a) {byte var2 = -1;switch(a.hashCode()) {case 49:if (a.equals("1")) {var2 = 0;}break;case 50:if (a.equals("2")) {var2 = 1;}}switch(var2) {case 0:System.out.println("1");break;case 1:System.out.println("2");break;default:System.out.println("3");}}可以看见,
JDK7 所支持的String类型是通过获取String的hashCode来进行选择的 , 也就是本质上还是int.为什么String可以这样干?这取决于String是一个不变类 。为了防止hash碰撞,自动生成的代码中更加保险的进行了再来看看equals判断 。
Enumpublic static void switchTest(Fruit a) {switch (a) {case Orange:System.out.println("Orange");break;case Apple:System.out.println("Apple");break;default:System.out.println("Banana");break;}}
推荐阅读
- 二 Java多线程-线程关键字
 - switch上古卷轴5mod怎么用(switch上古卷轴5mod视频)
 - 说说 Redis 事务
 - Switch什么时候出Pro_SwitchPro什么时候上市
 - 为了讲明白继承和super、this关键字,群主发了20块钱群红包
 - Vue中使用Switch开关用来控制商品的上架与下架情况、同时根据数据库商品的状态反应到前台、前台修改商品状态保存到数据库
 - switch为什么这么火_switch火爆原因
 - 微信朋友圈怎么转发图片说说(微信想转发朋友圈的说说和图片)
 - 说说芦荟胶 我一共用过4款芦荟胶,分别是自然乐园芦荟胶、丹姿芦荟胶、韩束芦荟胶和百雀羚三生花芦荟胶。
 - 说说传说中的KFC御用豆浆,为什么这么好喝
 
