利用字节码解决java中遇到的问题

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&gt;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>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值