变量的自增操作,如
i++
++i
i+=1
i=i++
这些自增操作的算术运算可能计算的最后结果是一样,仅从代码层面很难看出它们的异同。下面将从字节码指令的角度去分析这些操作的不同之处。
i++
与++i
的区别
如果只是进行变量的自增的运算,不涉及赋值操作,那么i++
和++i
在字节码指令层面上是执行相同的指令
可以看出i++
与++i
的字节码指令是一样的,都是先将操作数10
压入操作数栈,然后保存到局部变量表索引为1
的位置,也就是保存变量i
的位置,然后将局部变量表索引为1
的位置的变量的值加1
。
但是如果i++
与++i
涉及到赋值操作,那么字节码指令就会有所不同
如果赋值操作是a = i++
,执行的字节码顺序是:
- 将操作数
10
压入操作数栈 - 将操作数
10
保存到局部变量表索引为1
的位置,即保存在变量i
中 - 将变量
i
的值重新压入操作数栈中(此时压入的是操作数还是10
) - 将变量
i
的值进行加1
操作 - 最后把操作数栈中的操作数
10
保存到局部变量表索引为2
的位置,即保存在变量a
中
如果赋值操作是a = ++i
,执行的字节码顺序是:
- 将操作数
10
压入操作数栈 - 将操作数
10
保存到局部变量表索引为1
的位置,即保存在变量i
中 - 将变量
i
的值进行加1
操作 - 将变量
i
的值重新压入操作数栈中(此时压入的是操作数是11
) - 最后把操作数栈中的操作数
11
保存到局部变量表索引为2
的位置,即保存在变量a
中
二者不同之处在于iload_1
和iinc 1 by 1
这两条指令的执行先后顺序,如果是a = i++
运算,会先把i
的旧值压入操作数栈中,最后赋值给变量a
,如果是a = ++i
运算,会先进行加1
操作,然后把加1
后的新值压入操作数栈中,最后把新值赋值给变量a
i+=1
与i=i+1
的区别
从字节码可以看出i+=1
运算执行的是自增加1
操作
而i=i+1
运算执行的是两个操作数相加add
操作
i=i++
运算
这个涉及到变量的自增以及赋值运算,和a=i++
运算差不多,但是要注意的是变量i
的值会发生覆盖
- 将操作数
10
压入操作数栈中 - 保存操作数
10
到变量i
中 - 将变量
i
的值重新压入栈中(此时压入栈中的操作旧值10
) - 变量
i
的值加1
(此时变量i的值是11
) - 最后将操作数栈中的操作数
10
保存到变量i
中(发生覆盖,操作数10
覆盖了操作数11
)