java字節(jié)碼判斷對象應用是否被修改

原創(chuàng)

1 背景

在學習并發(fā)的時候看到了ConcurrentLinkedQueue隊列的源碼,剛開始的時候是看網(wǎng)上的帖子,然后就到IDE里邊看源碼,發(fā)現(xiàn)offer()方法在1.7版的時候有過修改。


樓主的問題不是整個方法,而是其中的一截代碼“(t != (t = tail))”,有點發(fā)暈,t是個引用,而修改引用的時候不是都修改嗎?怎么還會判斷是否相等呢 ?

2 為了解決這個問題,寫個測試方法。如下:

publicclassReferTest {

publicstaticvoidmain(String[] args) {

ReferTest a =newReferTest();

booleanb= (a != (a =newReferTest()));

}

}

答案:b= true。

說明 a != a,這個就更暈了。在度娘和谷歌上都查不到什么有用的資料,關鍵是不好描述,引用不等于引用?

再往下樓主就猜測了,引用的東西一般都和棧有關,就想看看方法的字節(jié)碼指令。使用javap命令解釋了方法的字節(jié)碼指令。




有用的方法看main方法的指令,樓主沒有接觸過字節(jié)碼指令,所以找個指令集學學了一下。在這里解釋下指令的意義,在這里記錄一下。


注意引用1是在命令8的時候加載的a的值,而引用2是新的引用,為什么出現(xiàn)這種情況,原因是if_acmpeq指令是比較兩個棧頂?shù)闹凳欠褚粯印?br>

所以在"!="號的兩端的值需要加載到棧頂,而右邊是一個表達式,所以先加載左邊的值到棧頂然后再去執(zhí)行右邊的表達式,表達式的結果放入棧頂,這個時候a引用1先加載,而表達式的結果會改變a變量的值,但是不會改變棧頂?shù)闹怠?/p>

所以就出現(xiàn)不一致的情況了。

同理,通過這個方式可以判斷對應的引用是否改變了。

ps:跟同事講解的時候,又分析了 i=i++ 、 i=++i、i= i+1的字節(jié)碼,發(fā)現(xiàn) i++ 使用的是iinc的命令,而i=i+1使用的是iadd指令。


最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容