i=0;i=i++为什么等于0这个问题困扰了我好长的一段时间<wbr style="font-family:Verdana,����; font-size:14px; background-color:rgb(238,238,238)"><span style="font-family:Verdana,����; font-size:14px; background-color:rgb(238,238,238)">,结果前段时间还试图从虚拟机那个层面进行解释,但无论是线程还是</span><wbr style="font-family:Verdana,����; font-size:14px; background-color:rgb(238,238,238)"><span style="font-family:Verdana,����; font-size:14px; background-color:rgb(238,238,238)">方法调用都不能解释其现象,发现方向性错误,这只是一个语言的特性</span><wbr style="font-family:Verdana,����; font-size:14px; background-color:rgb(238,238,238)"><span style="font-family:Verdana,����; font-size:14px; background-color:rgb(238,238,238)">而已。在java
lang spec中提到:</span><br style="font-family:Verdana,����; font-size:14px; background-color:rgb(238,238,238)"><span style="font-family:Verdana,����; font-size:14px; background-color:rgb(238,238,238)">1、java运算符的优先级++符是大于=的。</span><br style="font-family:Verdana,����; font-size:14px; background-color:rgb(238,238,238)"><span style="font-family:Verdana,����; font-size:14px; background-color:rgb(238,238,238)">2、The result of the postfix increment expression is not a variable, but a value.后++符表达式的结果是个值而不是一个变量。</span>
<p style="line-height:21px; margin-top:10px; margin-bottom:10px; font-family:Verdana,����; font-size:14px; background-color:rgb(238,238,238)">
也就是说后++符先将自己的值存储起来,然后对变量进行++;<br>
再进行赋值操作,也就是将先存储起来的值赋给变量i<wbr>,这样的操作就导致了i值被置为0了</wbr></p>
<p style="line-height:21px; margin-top:10px; margin-bottom:10px; font-family:Verdana,����; font-size:14px; background-color:rgb(238,238,238)">
<br>
对于C和C++来说不一样,在讲到m=<span class="st" id="st" name="st"><span style="background-color:rgb(255,255,136)">i++</span></span>操作时<wbr>,C语言是先将i的值赋给了m,然后将i值++,这样i=i+<wbr>+的结果自然就是1了,c的实现中是不存在那个中间的值的存储的。</wbr></wbr></p>
<p style="line-height:21px; margin-top:10px; margin-bottom:10px; font-family:Verdana,����; font-size:14px; background-color:rgb(238,238,238)">
<br>
由于java和c不同的语言特性,导致了i=<span class="st" id="st" name="st"><span style="background-color:rgb(255,255,136)">i++</span></span>的不同之处<wbr>,前面的笔记中已经提到,由于java lang spec中的一些细微规定,导致其运行结果的不同<wbr>,我们可以用个例子来看i=<span class="st" id="st" name="st"><span style="background-color:rgb(255,255,136)">i++</span></span>在jvm中实际的运行过程。<br>
源程序test.java:<br>
public class test {<br>
public test() {<br>
}<br>
public static void main(String[] args) {<br>
int i=0;<br>
i=<span class="st" id="st" name="st"><span style="background-color:rgb(255,255,136)">i++</span></span>;<br>
}</wbr></wbr></p>
<p style="line-height:21px; margin-top:10px; margin-bottom:10px; font-family:Verdana,����; font-size:14px; background-color:rgb(238,238,238)">
}<br>
我们用javap来看其实际的虚拟机指令集:<br>
C:\JBuilderX\jdk1.4\bin>javap -c -classpath "d:/" test<br>
Compiled from "test.java"<br>
public class test extends java.lang.Object{<br>
public test();<br>
Code:<br>
0: aload_0<br>
1: invokespecial #1; //Method java/lang/Object."":()V<br>
4: nop<br>
5: return</p>
<p style="line-height:21px; margin-top:10px; margin-bottom:10px; font-family:Verdana,����; font-size:14px; background-color:rgb(238,238,238)">
public static void main(java.lang.String[]);<br>
Code:<br>
0: iconst_0//常数0入栈<br>
1: istore_1//i赋值,常数值出栈<br>
//至此完成i=0;<br>
2: iload_1//装载变量i,0入栈<br>
//第2步是特殊的一步,这步将i值先行保存,以备赋值使用<br>
3: iinc 1, 1//变量值增加,栈内值不变<br>
//至此完成<span style="background-color:rgb(255,255,136)"><span class="st" id="st" name="st">i++</span><br></span> 6: istore_1//i赋值,0出栈。<br>
//至此完成i=<span style="background-color:rgb(255,255,136)"><span class="st" id="st" name="st">i++</span><br></span> 7: nop//donothing<br>
8: return</p>
<p style="line-height:21px; margin-top:10px; margin-bottom:10px; font-family:Verdana,����; font-size:14px; background-color:rgb(238,238,238)">
}</p>
<p style="line-height:21px; margin-top:10px; margin-bottom:10px; font-family:Verdana,����; font-size:14px; background-color:rgb(238,238,238)">
对比而言,对于<span class="st" id="st" name="st"><span style="background-color:rgb(255,255,136)">i++</span></span>而言,i=<span class="st" id="st" name="st"><span style="background-color:rgb(255,255,136)">i++</span></span>指令多了两步,2和6<br>
其实这两步是赋值符号引起的,有意思的是第二步出现的时机<wbr>,是在iinc之前,这就是因为java lang spec中规定的。</wbr></p>
<p style="line-height:21px; margin-top:10px; margin-bottom:10px; font-family:Verdana,����; font-size:14px; background-color:rgb(238,238,238)">
<br></p>
<p style="line-height:21px; margin-top:10px; margin-bottom:10px; font-family:Verdana,����; font-size:14px; background-color:rgb(238,238,238)">
本文转载于:<a href="http://www.blogjava.net/dreamstone/archive/2006/11/04/79058.html">http://www.blogjava.net/dreamstone/archive/2006/11/04/79058.html</a></p>
</wbr></wbr></wbr>
利用字节码解决java中遇到的问题
最新推荐文章于 2025-04-24 09:43:37 发布