用javap 反编译命令解释i=i++问题

看下面的简单程序:i的输出结果是多少?(sun 公司2005年的面试题曾出过一道类似的)
class Hello{
   public static void main(String arg[]){
        int i=0;
        i=i++;
        System.out.print(i);
}
}

先说结果:输出为0

解释:为了弄清楚此程序在java虚拟机中的运行过程,我们用javap反编译命令对javac编译命令生成的Hello.class文件进行了编译结果如下:

class Hello extends java.lang.Object{
Hello();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

我们主要看main函数部分:

首先我们要明白:在java 虚拟机中有两个存储区:一个是暂存区(堆栈),一个是变量区。语句istore_1是将堆栈中的值弹出存入相应的变量区(赋值);语句iload_1是将变量区中的值暂存如堆栈中。因为i++是后加操作,即先完成赋值操作,所以 2: iload_1命令即将变量区的0转存到堆栈中,之后完成3: iinc 1, 1即在变量区完成自加,此时变量区的i值为1,之后经 6: istore_1命令又将堆栈中的值0赋值给了变量区的i之后经print函数输出。所以值为0.

为了对比我们看一下i=++i的情况:

public static void main(java.lang.String[]);
  Code:
   0:   iconst_0
   1:   istore_1
   2:   iinc    1, 1
   5:   iload_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.print:(I)V
   14:  return

}

可以看出先在变量区自加2: iinc 1, 1,之后在将变量区的i值转存的堆栈,再经6: istore_1将堆栈中的值赋给变量区。所以输出为1.

在给出一个只有i++的:

public static void main(java.lang.String[]);
  Code:
   0:   iconst_0
   1:   istore_1
   2:   iinc    1, 1
   5:   getstatic       #2; //Field java/lang/System.out:Ljava/io/PrintStream;
   8:  iload_1
   9:  invokevirtual   #3; //Method java/io/PrintStream.print:(I)V
   12:  return

}



 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值