Java switch能用数学吗_说说Java中你不知道switch关键字

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_0

1: lookupswitch { // 2

1: 28

2: 39

default: 50

}

...

这里面省略一些代码。

可以发现,switch是通过lookupswitch指令实现。那么lookupswitch指令是干嘛的呢?

在Java se8文档中的描述可以大概知道:

switch可以被编译为两种指令lookupswitch:当switch的case比较稀疏的时候,使用该指令对int值的case进行一一比较,直至找到对应的case(这里的查找,可以优化为二分查找)

tableswitch:当switch的case比较密集的时候,使用case的值作为switch的下标,可以在时间复杂度为O(1)的情况下找到对应的case(可以类比HashMap)

并且文档中还有一段描述:

现在,我们应该能够明白,为什么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是一个不变类。

再来看看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;

}

}

编译生成Test.class。拖入IDEA进行反编译得到如下代码:public static void switchTest(Fruit a) {

switch(1.$SwitchMap$com$dengchengchao$Fruit[a.ordinal()]) {

case 1:

System.out.println("Orange");

break;

case 2:

System.out.println("Apple");

break;

default:

System.out.println("Banana");

}

}

可以看到,枚举支持switch更加简单,直接通过枚举的顺序即可作为相关case

总之:switch的设计按道理来说,是比if-else要快的,但是在99.99%的情况下,他们性能差不多,除非case分支量巨大,但是在case分支过多的情况下,一般应该考虑使用多态重构了。

switch虽然支持byte,int,short,char,enum,String但是本质上都是int,其他的只是编译器帮你进行了语法糖优化而已。

如果觉得写得不错,欢迎关注微信公众号:逸游Java ,每天不定时发布一些有关Java进阶的文章,感谢关注

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值