[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:L
java/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:L
java/io/PrintStream;
8: iload_1
9: invokevirtual #3; //Method
java/io/PrintStream.print:(I)V
12: return
}
摘自
Android_qhdxuan的专栏