i++和++i探秘

从最开始接触编程,就一直有人告诉我们i++和++i不一样,但是没有告诉我,为什么会不一样。呵呵~~

今天来了解下为什么会不一样。

 

首先,来认识一下本文的核心工具:javap命令

javap是jdk自带的一个工具,可以反编译,也可以查看java编译器生成的字节码,是分析代码的一个好工具。

通过它,我们可以对照源代码和字节码,从而了解很多编译器内部的工作。

javap命令格式:

javap [ options ] class

options 选项:

-l                 输出行和变量的表
-public         只输出public方法和域
-protected     只输出public和protected类和成员
-package     只输出包,public和protected类和成员,这是默认的
-private       输出所有类和成员
-s               输出内部类型签名
-c               输出分解后的代码,例如,类中每一个方法内,包含java字节码的指令,
-verbose     输出栈大小,方法参数的个数                       

 ok,回到正题。先写个HelloWord小程序

public class Hello {
    public static void main(String args[]){
        int i=2;
        i++;
        int j=1;
        ++j;
    }
}

将其编译,编译完成之后,执行如下命令:

javac Hello.java
javap -c Hello

得到如下输出:

E:\>javap -c Hello
Compiled from "Hello.java"
public class Hello extends java.lang.Object{
public Hello();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

public static void main(java.lang.String[]);
  Code:
   0:   iconst_2    //把2放到栈顶
   1:   istore_1    //把栈顶的值放到局部变量1中,即i中
   2:   iinc    1, 1    //这个指令,把局部变量1,也就是i,增加1,这个指令不会导致栈的变化,i此时变成3了

5: iconst_1 //把1放到栈顶 6: istore_2 //把栈顶的值放到局部变量2中,即j中 7: iinc 2, 1 //把局部变量2,也就是j的值,增加1,这个指令不会导致栈的变化,j变成2了 10: return }

 

下面在再来看看这个程序:

public class Hello {
    public static void main(String args[]){
        int i=2;
        i=i++;
        int j=1;
        j=++j;
    }
}

再来看看这个反编译的结果:

E:\>javap -c Hello
Compiled from "Hello.java"
public class Hello extends java.lang.Object{
public Hello();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

public static void main(java.lang.String[]);
  Code:
   0:   iconst_2  //把2放到栈顶(栈顶=2)
   1:   istore_1  //把栈顶的值放到局部变量1中,即i中(i=2,栈顶=2)
   2:   iload_1   //把局部变量1的值,即2放到栈顶,也就是说此时栈顶的值是2(i=2,栈顶=2)
   3:   iinc    1, 1  //这个指令,把局部变量1,也就是i,增加1,这个指令不会导致栈的变化,i此时变成3了(i=3,栈顶=2)
   6:   istore_1  //把栈顶的值放到局部变量1中,即i中,栈顶的值是2! (i=2,栈顶=2)

7: iconst_1 //把1放到栈顶(栈顶=1) 8: istore_2 //把栈顶的值放到局部变量2中,即j中(j=1,栈顶=1) 9: iinc 2, 1 //把局部变量2,也就是j,增加1,这个指令不会导致栈的变化,j此时变成2了(j=2,栈顶=1) 12: iload_2 //把局部变量2的值,即2放到栈顶(j=2,栈顶=2) 13: istore_2 //将栈顶值放到局部变量2中,即j中,所以j=2了(j=2,栈顶=2) 14: return }

 

 

 

 

posted @ 2013-03-06 18:07  yejg1212  阅读(375)  评论(0编辑  收藏  举报