美文网首页
JAVA i = i++;

JAVA i = i++;

作者: iFavorite | 来源:发表于2017-09-29 16:39 被阅读51次

int i = 0;

i = i++;

System.out.println(i); // ?

最终结果是什么? JAVA 结果为 0, C/C++结果为 1.

JAVA

public classMain {

    public static voidmain(String[] args) {

        Integer i =0;

        i = i++;

        System.out.println(i);

        }

}

http://wangwengcn.iteye.com/blog/1622195 

Java虚拟机栈(JVM Stack)描述的是Java方法执行的内存模型,而JVM内存模型是基于“栈帧”的,每个栈帧中都有局部变量表操作数栈(还有动态链接、return  address等).

局部变量表:变量值存储空间.存放方法参数和方法内部定义的局部变量.

操作数栈:虚拟机把操作数栈作为它的工作区——大多数指令都要从这里弹出数据,执行运算,然后把结果压回操作数栈。

如下图是JAVAP转换成的JVM指令.

JVM指令详解: http://blog.csdn.net/hudashi/article/details/7062675


根据上面的JVM指令,局部变量表 index_1,index_2,index_3被使用到.  而index_1是实际i的值.

6:保存原始的i值到index_2

之后没有使用index_2

19:重新使用index_2的值,并覆盖了index_1的值.

在我看来,可能是JAVA的一个bug.

JVM里面有两个存储区,一个是暂存区(是一个堆栈,以下称为堆栈),另一个是变量区。

JVM会这样运行这条语句,

步骤1: 把 i 值(其值是0)拷贝到临时变量区。

步骤2: i 值加1,这时候 i 的值是1。

步骤3: 返回临时变量区的值,注意这个值是0,没修改过。

步骤4: 返回值赋值给 i,此时 i 值被重置成0。

C/C++中没有另外设置一个临时变量或是临时空间来保存 i,所有操作都是在一个内存空间中完成的,所以在C/C++中是1。


C/C++

http://blog.csdn.net/oldmanzhao/article/details/43851877 

int c = ++i;

012D1384  mov        eax,dword ptr [i]

012D1387  add         eax,1

012D138A  mov        dword ptr [i],eax

012D138D  mov        ecx,dword ptr [i]

012D1390  mov        dword ptr [c],ecx

可以看到这个操作在完成了前三部之后做了两个mov把最终的i值放到了c中


int b = i++;

012D1375  mov        eax,dword ptr [i]

012D1378  mov        dword ptr [b],eax

012D137B  mov        ecx,dword ptr [i]

012D137E  add        ecx,1

012D1381  mov        dword ptr [i],ecx

结果稍有不同,在把i的值mov到eax之后又立即把eax放到了b中,随后的三步保持与之前一致只不过寄存器换成了ecx,正好符合i++的特性.


那么,JVM指令与汇编命令之间的关系与映射是怎样的?

不知道为什么,在mac上,使用visual code和sublime跑C++的的这段程序,结果却是0. 在Windows上,这段程序结果却是1.

可能是编译器不同吧?

相关文章

  • Java中的i++ 和 ++i 在for循环使用

    Java的i++ 和++i 的区别i++:先赋值,后计算;++i;先计算,后赋值。 for循环中的i++和++i...

  • JAVA i = i++;

    int i = 0;i = i++;System.out.println(i); // ? 最终结果是什么? JA...

  • java知识集合

    i=0;i= i++ ;结果i=0 因为先引用,后计算java使用中间变量缓存机制i=i++可以分为几步:1. t...

  • kotlin for 循环

    kotlin 与java 的for循环是有区别的 java: for(int i=0;i<9;i++){ } ko...

  • Java i++ 与 ++i

    i++ 是后加运算符,即先赋值,然后自增长1。 ++i 是前加运算符,先自增长1,然后再赋值。 所以,下面的代码:

  • 自增、赋值运算符

    1.自增 int i = 3; int a = i++ + i++ + i++;//第①个i++表达是值为3,i=...

  • JavaScript没有块级作用域

    如下代码: for (var i=0;i<3;i++) { } alert(i); 结果:弹框弹出3; 和java...

  • java跳出双重for循环,跳出双重for循环

    java跳出双重for循环,跳出双重for循环 跳出一层: for(int i=0;i<10;i++){ f...

  • 某疆笔试

    题型 选择单选多选 问答 选择 1、int i=2; int x=(i++)+(i++)+(i++);x=? x=...

  • Java i++ 和 ++i原理

    i++ 和 ++i原理 i++ 即后加加,原理是:先自增,然后返回自增之前的值++i 即前加加,原理是:先自增,然...

网友评论

      本文标题:JAVA i = i++;

      本文链接:https://www.haomeiwen.com/subject/wegiextx.html