无意中看到这样一个问题:
int a = 1;
a = a++;
此时 a = ?,我自己测试了一下,vs2008中得到a = 2 ;在linux中用gcc编译得到的结果也是2,而当用java语言时,在JDK7环境下得到的结果a = 1;
为了搞清楚是怎么回事,进行了一点研究,如下:
在vs2008中有这样的汇编代码:
a = a++;
00881445 8B 45 F8 mov eax,dword ptr [a]
00881448 89 45 F8 mov dword ptr [a],eax
0088144B 8B 4D F8 mov ecx,dword ptr [a]
0088144E 83 C1 01 add ecx,1
00881451 89 4D F8 mov dword ptr [a],ecx
很清楚明了吧! 即分解为:a = a; a++; 两句,所以结果为a = 2; 很自然。接下来看看java语言中是怎么处理的:
L0
LINENUMBER 4 L0
ICONST_1
ISTORE 1
L1
LINENUMBER 5 L1
ILOAD 1
IINC 1 1
ISTORE 1
L2
随口说一下:java语言编译后是运行在java虚拟机中的,java虚拟机值的传递都是基于栈的,没有用寄存器。以上是它的字节码助记符,可以清楚的看到它的
工作原理:可能有人看不懂,那我解释一下:
L0与L1之间的代码的意思是:ICONST_1:把常量1压入栈,ISTORE 1:把栈顶元素(值为1)弹出赋给本地变量a, L1与L2之间:ILOAD 1:把本地变量中索引为1(也就是a)的变量压入栈, IINC 1 1:
让本地变量中索引为1的变量(也就是a,因为我们只定义了一个本地变量)的值自加1,此时变量 a = 2, ISTORE 1:把栈顶元素(值为1)弹出赋给本地变量中的变量a, 所以a = 1。 也不知道java虚拟机怎么会这样处理,导致最终a的
值为1而不是2.