很對不起作者,當(dāng)時看到這篇文章的時候因為有事情忙,所以直接拷貝發(fā)到郵箱,這個時候轉(zhuǎn)出來,就找不到出處了,如果哪位找到出處給我留個言,我把出處補(bǔ)上。謝謝
i=0;i=
i++為什么等于0這個問題困擾了我好長的一段時間
,結(jié)果前段時間還試圖從虛擬機(jī)那個層面進(jìn)行解釋,但無論是線程還是方法調(diào)用都不能解釋其現(xiàn)象,發(fā)現(xiàn)方向性錯誤,這只是一個語言的特性而已。在java lang spec中提到:
1、java運(yùn)算符的優(yōu)先級++符是大于=的。
2、The result of the postfix increment expression is not a variable, but a value.后++符表達(dá)式的結(jié)果是個值而不是一個變量。
也就是說后++符先將自己的值存儲起來,然后對變量進(jìn)行++;
再進(jìn)行賦值操作,也就是將先存儲起來的值賦給變量i,這樣的操作就導(dǎo)致了i值被置為0了
對于C和C++來說不一樣,在講到m=i++操作時,C語言是先將i的值賦給了m,然后將i值++,這樣i=i++的結(jié)果自然就是1了,c的實現(xiàn)中是不存在那個中間的值的存儲的。
由于java和c不同的語言特性,導(dǎo)致了i=i++的不同之處,前面的筆記中已經(jīng)提到,由于java lang spec中的一些細(xì)微規(guī)定,導(dǎo)致其運(yùn)行結(jié)果的不同,我們可以用個例子來看i=i++在jvm中實際的運(yùn)行過程。
源程序test.java:
public class test {
? public test() {
? }
? public static void main(String[] args) {
??? int i=0;
??? i=i++;
? }
}
我們用javap來看其實際的虛擬機(jī)指令集:
C:\JBuilderX\jdk1.4\bin>javap -c? -classpath "d:/" 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."":()V
?? 4:?? nop
?? 5:?? return
public static void main(java.lang.String[]);
? Code:
?? 0:?? iconst_0?//常數(shù)0入棧
?? 1:?? istore_1?//i賦值,常數(shù)值出棧
?//至此完成i=0;
?? 2:?? iload_1??//裝載變量i,0入棧
?//第2步是特殊的一步,這步將i值先行保存,以備賦值使用
?? 3:?? iinc??? 1, 1?//變量值增加,棧內(nèi)值不變
?//至此完成i++
?? 6:?? istore_1?//i賦值,0出棧。
?//至此完成i=i++
?? 7:?? nop??//donothing
?? 8:?? return
}
對比而言,對于i++而言,i=i++指令多了兩步,2和6
其實這兩步是賦值符號引起的,有意思的是第二步出現(xiàn)的時機(jī),是在iinc之前,這就是因為java lang spec中規(guī)定的。