public class Test{ public static void main(String[] args){ int i=0; int a=i++; System.out.println(i); System.out.println(a); } } 对于上述代码,发现一个朋友在讨论这个问题,今天仔细研究了一下,发现其中的问题仍是不少的。 1.执行javap -c Test E:\第二阶段练习文件\js\test>javap -c Test Compiled from "Test.java" public class Test extends java.lang.Object{ public Test(); 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_0 1: istore_1 2: iload_1 3: iinc 1, 1 6: istore_2 7: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream; 10: iload_1 11: invokevirtual #3; //Method java/io/PrintStream.println:(I)V 14: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream; 17: iload_2 18: invokevirtual #3; //Method java/io/PrintStream.println:(I)V 21: return } 这是执行的结果,仔细研究这个反编译过程,并查找了一些资料,以为应该是解决了这个问题。 2.谈谈体会: 开始的时候在栈中放入0,为i的引用。 而后计算i++,很明显,a的值为1,而后i为2. 固然这个谁都知道,那i=i++呢?若是是这个问题,就比较复杂了,可是想通了以后,你就知道我为何要写上述的程序了。 来看看i=i++的程序: public class Test{ public static void main(String[] args){ int i=0; i=i++; System.out.println(i); } } 执行反编译的结果: E:\第二阶段练习文件\js\test>javap -c Test Compiled from "Test.java" public class Test extends java.lang.Object{ public Test(); 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_0 1: istore_1 2: iload_1 3: iinc 1, 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.println:(I)V 14: return } 结果是: 0 为何呢? 首先,在栈中放入0 而后,将i=i++中的i++计算,可知,要将i=0这个值赋给 i=i++ 中的前面的那个i,这就是java会给i分配一个新的虚拟空间来保存这个数据,而当后面的那个i计算为1以后,这个表达式就执行完毕,可是,此时,高潮来了。 前面的那个i中的值将会从栈中被取出并覆盖了后面的那个i,由于这里只许拥有一个i变量,后面的那个i原本是1,可是它的值在栈中被先取出来了,因此是开始为1,最后为0(这个0是由前面那个i放进去的)