最近,我在研究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这种方式。