用javap反编译命令解释i=i++问题
2736 点击·0 回帖
![]() | ![]() | |
![]() | [plain] 看下面的简单程序:i的输出结果是多少?(sun 公司2005年的面试题曾出过一道类似的) [java] class Hello{ public static void main(String arg[]){ int i=0; i=i++; System.out.print(i); } } 先说结果:输出为0 解释:为了弄清楚此程序在java虚拟机中的运行过程,我们用javap反编译命令对javac编译命令生成的Hello.class文件进行了编译结果如下: [plain] 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的情况: [plain] 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++的: [plain] 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 } 摘自 Android_qhdxuan的专栏 | |
![]() | ![]() |