javap解析i++与++i问题

2016-07-03  本文已影响223人  豆豆先生的小屋

相信不少从事java开发的人在刚开始接触java的时候都会遇到让人巨头疼的i++和++i问题,网上很多资料都是直接告诉结果而并没有说清楚为什么是这个结果,包括自己之前也是死记硬背,知其然不知其所以然,碰巧前几天在网上看到javap命令,现在在这里做一个小的总结,也顺便用这个命令来带大家从字节码的角度解析一下这虚拟机是如何处理这两个不同的命令的。

public class Test{
    public static void main(String[] args){
            int n = 0;
            for(int i = 0; i < 100; i++){
                n = n++;
            }
            System.out.println(n);
    }
}

你觉得结果是什么呢,是100,还是0。如果你对自己的结果不确信或者知道结果但是不知道为什么是这个结果的。请往下看。

javap是什么

具体定义请自行Google,我只知道javap -c 可以让我们看到编译后产生的字节码,对照源码和字节码会清楚很多。

public class Test{
    public static void main(String[] args){
            int i = 5;
    }
}

为方便起见,这里只看main部分的字节码

  public static void main(java.lang.String[]);
    Code:
       0: iconst_5  //将常量5入栈
       1: istore_1  //将栈顶的弹出,并存储在位置1的局部变量中,即"i"中
       2: return

是不是很简单,那我们来个稍微复杂点的

public class Test{
    public static void main(String[] args){
            int i = 5;
            int j = i;
    }
}

  public static void main(java.lang.String[]);
    Code:
       0: iconst_5  //把常量5入栈
       1: istore_1  //将栈顶的值弹出,并存储在位置1的局部变量中,即"i"中 ,此时"i"的值为5
       2: iload_1   //把位置1的局部变量压入栈中
       3: istore_2  //把栈顶的值弹出,并存储在位置2的局部变量中,即"j"中,此时"j"的值为5
       4: return

怎么样,也不难是吧,终于轮到我们的大boss出场了

public class Test{
    public static void main(String[] args){
            int i = 5;
            i = i++;
            int j = 6;
            j = ++j;
    }
}

最终结果 i = 5,j = 7!


public static void main(java.lang.String[]);
    Code:
       0: iconst_5        //把常量5入栈
       1: istore_1        //将栈顶的值弹出并存储在位置1的局部变量1中,即"i"中,此时"i"的值为5
       2: iload_1         //将位置1的局部变量压入栈,即"i"入栈,栈顶值为5
       3: iinc      1, 1  //将位置1的值加1,即"i"加1,此时"i"的值为6,注意这条指令不会改变栈顶的值
       6: istore_1        //将栈顶的值弹出并存储在位置1的局部变量中,即"i"中,此时"i"的值依然为5

       7: bipush     6    //将常量6入栈
       9: istore_2        //将栈顶的值弹出并存储在位置2的局部变量中,即"j"中,此时"j"的值为6
      10: iinc      2, 1  //将位置2的值加1,即"j"加1,此时"j"的值为7,注意这条指令不会改变栈顶的值
      13: iload_2         //将位置2的局部变量压入栈,即"j"入栈,栈顶值为7
      14: istore_2        //将栈顶的值弹出并存储在位置2的局部变量中,即"j"中,此时"j"的值为7

      15: return

从字节码中我么可以看出i++与++i的主要区别在于步骤2,3与步骤10,11的顺序是相反的,这是造成了最终解结果不同最终原因。

int temp = i;
i++;
i = temp;

看到这里你是不是对本文开始的题目理解的更透彻了呢!


THE END

如有错误之处还请大家不吝赐教,多多指正,共同进步!

上一篇 下一篇

猜你喜欢

热点阅读