int j = 100;
j = j++;
以上两行代码,在Java中的运行结果是100,在C/C++中的运行结果是101。可见,是不能从逻辑的角度来理解的。根本原因是,各种开发语言对j=j++的处理机制不同。
本文通过反编译手段,分析一下java的执行过程。
java完整代码如下。
public class jPlusPlus {
public static void main(String[] args) {
int j = 100;
j = j++;
}
}
使用IDEA编译或运行后,会在out目录中生成该类的class文件,如图所示。
在jPlusPlus.class所在目录中,使用以下命令对该class文件进行反编译
javap -c -l jPlusPlus.class
反编译的结果如下。
D:\github\JavaCore\src\WeiXinGZH\out\production\WeiXinGZH>javap -c -l jPlusPlus.class
Compiled from "jPlusPlus.java"
public class jPlusPlus {
public jPlusPlus();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 1: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this LjPlusPlus;
public static void main(java.lang.String[]);
Code:
0: bipush 100
2: istore_1
3: iload_1
4: iinc 1, 1
7: istore_1
8: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
11: iload_1
12: invokevirtual #3 // Method java/io/PrintStream.println:(I)V
15: return
LineNumberTable:
line 5: 0
line 6: 3
line 7: 8
line 40: 15
LocalVariableTable:
Start Length Slot Name Signature
0 16 0 args [Ljava/lang/String;
3 13 1 j I
}
有图有真相。
现在分析图中红色圈起来的部分。也是j=j++的核心内容:
0:ipush 100 :入栈操作,将数值100压入栈顶。
2:istore_1:出栈操作。将栈顶的数据(即100)弹出,并赋值给第1个变量(即变量j=100)。
3:iload_1:入栈操作。将第1个变量入栈,即此时的栈顶是j(j=100)。
4:iinc 1,1 :自增操作。对第1个变量进行自增1操作,即对局部变量j执行j++。注意,此时有两个j,局部变量表中的j(即变量j)的值是101;而栈顶的j仍然是100。
7:istore_1:出栈操作。将栈顶的数据(即j=100)弹出,赋值给第1个变量j(即变量j=栈顶j100,也就是局部变量j又从101变回了100)。
综上,在java中j=j++相当于什么都没干。
对于“不同编程语言对相同代码的执行结果不同”这一问题,个人建议不用深究,只要了解其大概过程,知道分析的方法,并记住结论即可。
- 完 -