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

    输出。

     

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

  • 相关阅读:
    SQL分页存储过程——表名、返回的列、排序字段、排序类型、条件、页尺寸、页码
    SQL——触发器——插入触发器——边学边项目写的。
    SQL链表查询 数据库为空
    【错误积累】更新失败,数据包解压时出现错误!
    VS使用技巧(转)
    命令模式
    代理模式
    模板方法模式
    享元模式
    MongoDB 分片2
  • 原文地址:https://www.cnblogs.com/lsx1993/p/4796300.html
Copyright © 2011-2022 走看看