zoukankan      html  css  js  c++  java
  • java中i=i++问题分析

    http://www.ticmy.com/?p=43

    重点:局部变量表 和 操作数栈的执行过程。

    使用javac编译后再使用javap -c Test反编译这个类查看它的字节码,如下(只摘取main方法):

    public static void main(java.lang.String[]);

    Code:

    0: iconst_0

    1: istore_1

    2: iload_1

    3: iinc 1, 1

    6: istore_1

    7: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;

    10: iload_1

    11: invokevirtual #3; //Method java/io/PrintStream.println:(I)V

    14: return

    这里,我从第0行开始分析(分析中【】表示栈,栈的底端在左边,顶端在右边):

    0:将常数0压入栈,栈内容:【0】

    1:将栈顶的元素弹出,也就是0,保存到局部变量区索引为为1(也就是变量i)的地方。栈内容:【】

    2:将局部变量区索引为1(也就是变量i)的值压入栈,栈内容:【0】

    3:将局部变量区索引为1(也就是常量i)的值加一,此时局部变量区索引为1的值(也就是i的值)是1。栈内容:【0】

    6:将栈顶元素弹出,保存到局部变量区索引为1(也就是i)的地方,此时i又变成了0。栈内容:【】

    7:获取常量池中索引为2所表示的类变量,也就是System.out。栈元素:【】

    10:将局部变量区索引为1的值(也就是i)压入栈。栈元素:【0】

    11:调用常量池索引为3的方法,也就是System.out.println

    14:返回main方法

    =================================================================

    Java使用了中间缓存变量机制:

    i=i++;等同于:

    temp=i (等号右边的i)

    i=i+1;      (等号右边的i)

    i=temp;   (等号左边的i)

    i=++i;则等同于:

    i=i+1;

    temp=i;

    i=temp;

     

    =================================================================

    15: iload_2       //将局部变量区2号索引的变量i0压入操作数栈 

    16: iinc     2, 1 //将局部变量区2号索引的值加1,操作数栈不发生变化 

    19: istore_2      //将栈顶的0弹出,赋给局部变量区2号索引的

     

    =================================================================

     

    main fremin i 在各自 (运行时的当前栈帧<StackFrame>)的局部变量表<Local Variable Table>中,两个变量不一样。main调用fremin结束之后退栈,然而并没有改变main的栈帧的局部变量表里 i 的值。 

     

    i=i++i++的汇编指令是(iinc 11),他只改变本地变量表的值,但是  i= 赋值的时候,操作数栈的栈顶还是0,存到本地变量表,又把slot1覆盖成0,所以得0.

    iconst_0// 0

    istore_1//slot 1 : i=0

    iload_1 //取出0

    iinc 1,1 //slot 1: i=1

    istore_1// slot 1 = 0覆盖

    iload_1 //println的还0

    输出。

     

    =================================================================

  • 相关阅读:
    JS搞基指南----延迟对象入门提高资料整理
    JavaScript使用自定义事件实现简单的模块化开发
    nodeJS+bootstarp+mongodb整一个TODO小例子
    nodeJS+express+Jade写一个局域网聊天应用(node基础)
    jQ1.5源码注释以及解读RE
    jQ1.5中的事件系统(低版本的事件系统)
    JS中的事件类型和事件属性的基础知识
    [转][mysql]创建函数失败(1418错误)mysql双主模式导致的问题
    MySQL数据库导入错误:ERROR 1064 (42000) 和 ERROR at line xx:
    Vmware由于centos升级内核不可运行(C header files matching your running kernel were not found)的解决方案
  • 原文地址:https://www.cnblogs.com/lsx1993/p/4796300.html
Copyright © 2011-2022 走看看