JAVA If-else语句

本文主要内容如下:

1.从java字节码的角度去看if…else语句.

3.Java虚拟机会对if…else做哪些优化.

4.如何让if…else更易读(参考了代码大全和重构)

 

1.  从java字节码的角度去看if…else语句。

相比于汇编指令集,java字节码指令集要更少,更简单。在汇编语言不仅有直接跳转指令,还有间接跳转。同时根据目标指令的偏移量大小,还分为近跳,远跳等等。

 

一般来说,如果从底层的角度去看待分支语句,会将分支语句分为两大类,一是条件分支,二是无条件分支。

1.1条件分支

简而言之,条件分支就是通过将一个值与另一个值进行比较,如果结果为真,则继续执行。如果结果非真,则跳转到某一指令处执行。

请看如下一段字节码,这是我自己写的:

4 If_icmpne  11

7 Iconst_1

8 Iconst_2

9 Iadd

10 Istore_1

11 return

现解释一下这段字节码:

If_cmpne:弹出栈顶两个元素,如果不相等,则为true,如果相等,则为false;

If_cmpne指令便是一个条件分支指令,他通过比较栈顶的两个元素是否不等,而采取相应的操作。在这段字节码中,如果栈顶的两个元素不等,则为真,继续执行接下来的语句。如果相等,则非真,跳转到偏移量为11所对应的字节码继续执行。在这里,偏移量11处的指令是一个return指令,直接返回。

 

1.2无条件分支

         在java字节码中有两个无条件分支指令,goto和goto_w.与条件分支指令不同的是,当java虚拟机执行到goto指令时,不会进行一些测试,从而根据结果是否为真而采取不同的操作,java虚拟机会直接跳转到goto指令中操作数所指示的指令。

 

 

2.  Java虚拟机可能会对if…else做哪些优化

请看如下两段代码,然后猜测哪一段代码的运行时性能会更好一些:

  

 void someMethod(){

        if(...){

            //一些代码

        }else{

            //一些代码

        }

}

 

    void someMethod(){

        if(...){

            firstMethod();

        }else{

            secondMethod();

        }

    }

   

    void firstMethod(){

        //一些代码

    }

   

    void secondMethod(){

        //一些代码

    }

 


答案是第二段代码的运行时效率会更高一些。

第二段代码的不同之处在于,将if和else后面的语句提炼到一个单独的小方法中,然后分别调用它们。

为什么第二段的代码要更好一些呢?答案在于虚拟机的智能优化。

Java虚拟机会将一个方法的字节码全部编译成本地指令,然后顺序执行它。正如后面即将讨论的,java虚拟机会特殊对待字节码中的分支语句,可以减少一些不必要的编译操作。

在第一段代码中,java虚拟机会将someMethod方法的字节码全部编译成本地指令,然后顺序执行他们。如果if语句的测试结果为真,则执行if后面的分支,如果if测试结果为假,则执行else后面的分支逻辑。

现在的问题时,在同一时间内,java虚拟机只会执行if和else两者中的一个。如果执行的if后面的分支,那么else后面的就不会执行。

既然else后面的分支逻辑不会执行,那么就没有必要对他进行编译。如果这是一个庞大的else语句,并且可能永远不会使用else,那么对他的编译就会造成一些没有必要的性能损失。

如果我们将if和else后面的代码分别提炼到一个单独的方法中,那么java虚拟机就会特殊对待这个分支语句。

这时候,java虚拟机不会对someMethod的字节码全部编译成本地指令。Java虚拟机会根据if的测试结果,有针对性的编译if或者else后面的方法。如果if测试为真,难么java虚拟机就会调用firstMethod方法,并编译这个方法。Java虚拟机不会再对secondMecond方法进行编译,因为这个方法没有被调用到。

现在,我们可以看出,在第二段代码中,性能会更好一些。尤其是当else是一个庞大的分支逻辑时,通过将他提炼到一个单独的secondMethod方法中,就只会在真正调用它的时候才会对其进行编译,从而提到了运行时的性能。

因此,在写代码中,应当尽可能的写一些短小的方法。短小的代码不仅会被优化,还具有易读,编译维护的优点。

 

3.如何让if…else更易读?

我始终遵循中重构以及代码大全一书中所给的建议,这里不可能将所有建议都列出来,只列举部分最常用的一部分:

1.             将if后面的测试提炼成一个单独的方法,然后调用它。分别将if和else后面的语句提炼成一个单独的方法,然后调用它们。

2.             尽量写“正逻辑“。既尽量写if(str==”sss”)而不是if(Str!=”sss”).

3.             如果是if…else语句链或者case语句,尽量将那些使用频率最高的,重要的,最易于想到的情况写在前面。因为在阅读代码的时候,最先发生的往往是那些使用频率最高的分支。如果这些分支在前面,那么就省去了阅读剩下代码的时间。

4.             如果可能,使用类对象来替换分支语句(使用多态重构分支语句)

5.             将深层嵌套的条件语句,使用卫字句替换。

6.             一个方法可能会返回一个null值,调用端会对这个null值进行测试。代码整洁之道一书中说,这是非常丑陋的代码。解决办法可以使用NULL对象对其进行重构,或者让这个方法抛出一个异常。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值