Java中a=a+3和a += 3一样吗?

最近,我在研究try->catch->finally的return问题的时候突然发现这么一个有趣的问题,对于a=a+3和a += 3是否一样?闲话少说,我们来一起看一下吧。按理说我们需要两段代码分别查看两种情况,然而这里我们为了方便,就用两个方法分析吧。

1.代码

/**
 * @author surpass
 * @date 2019/11/2
 */
public class ValueTest {

    public void test1(){
        int a = 0;
        a = a + 2;
    }
    public void test2(){
        int a = 0;
        a += 2;
    }
}

2. 反编译文件

通过执行javap -v class文件,查看输出内容。这里我们主要查看两个方法反编译部分。

1)方法test1的反编译部分

  public void test1();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=2, args_size=1
         0: iconst_0
         1: istore_1
         2: iload_1
         3: iconst_2
         4: iadd
         5: istore_1
         6: return
      LineNumberTable:
        line 10: 0
        line 11: 2
        line 12: 6
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       7     0  this   Lcn/surpass/jvm/review/ValueTest;
            2       5     1     a   I

2)方法test2的反编译部分

  public void test2();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=2, args_size=1
         0: iconst_0
         1: istore_1
         2: iinc          1, 2
         5: return
      LineNumberTable:
        line 14: 0
        line 15: 2
        line 16: 5
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       6     0  this   Lcn/surpass/jvm/review/ValueTest;
            2       4     1     a   I

3.差异性比较

3.1  对于code的第一行,我们很明显发现a+=3实例代码的操作数栈为1,而a=a+3的操作数栈为2。

3.2 执行代码的指令不一样。对于a+=3,iinc直接在局部变量表中进行操作,这里不涉及压栈的情况。而对于a = a+3,这里用到的指令为iadd,这个指令需要两个参数,所以会先将a所对应的值和3一次压入栈顶,然后执行指令,将结果放到栈顶,接下来,再把栈顶的值赋值到局部变量表中。

4. 总结

对于a=a+3会比a +=3多需要一个操作数栈,其次执行步骤a+=3也有明显优势,所以,从性能方面考虑,建议要尽量使用a+3这种方式。

 

 

 

 

 

 

 

发布了72 篇原创文章 · 获赞 24 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/oYinHeZhiGuang/article/details/102877582