Java中关于i=i++的问题解些
本文可转载演绎,但需要注明原作者和本文链接。
本文在JVM指令层次讲解i=i++之后,i的值不变的问题。.
背景知识
JVM在方法体中的操作指令,一部分是直接作用stack栈,也有一些部分是直接操作Local Variable(本地变量区/局部变量区)。
简单的介绍两个指令
ILOAD
将一个整数常量push到方法栈中。
ILOAD n 执行前stack
index | value |
---|---|
0 | … |
1 | |
… |
ILOAD n 执行后stack
index | value |
---|---|
0 | … |
1 | n |
… |
而本地变量区没有变化。
ISTORE
将一个整数常量pop出方法栈,并将该常量值赋值给本地变量区(Local Variable)。
ISTORE n 执行前stack
index | value |
---|---|
0 | … |
1 | x |
… |
ISTORE n 执行后stack
index | value |
---|---|
0 | … |
1 | |
… |
ISTORE n 执行前 Local Variable
index | value |
---|---|
0 | … |
… | |
n | … |
… |
ISTORE n 执行后Local Variable
index | value |
---|---|
0 | … |
… | |
n | x |
… |
IINC
将一个本地变量区(Local Variable)的整数常量值加1。
本地方法栈无变化。
ISTORE n 执行前 Local Variable
index | value |
---|---|
0 | … |
… | |
n | x |
… |
ISTORE n 执行后Local Variable
index | value |
---|---|
0 | … |
… | |
n | x + 1 |
… |
i++ VS ++i
在平时的讲解中,”i++“ 这条指定会在完成整个语句运算后执行,”++i“ 这条指令会在整个语句运算前执行。
实例讲解
i=i++
现在有一段代码如下
编译成指令后,其中i=i++的指令如下
应该有部分同学明白了,ILOAD指令先把i的原始值先被加载到了stack中,
然后IINC指令将本地变量中的i进行了+1操作,但是栈上的i还是原始值。
然后ISTORE指令又将栈上的i的原始变量值付给了本地变量i。
所以i相当于没做操作。
i=++i
代码如下
编译成指令后,其中i=i++的指令如下
IINC指令将本地变量中的i进行了+1操作,
ILOAD指令先把i+1的值先被加载到了stack中,
ISTORE指令stack上的新值赋值付给了本地变量i,
所以本地变量是+1后的值。