升級到JDK9的一個BUG,你了解嗎
概述
前幾天在一個群里看到一個朋友發了一個demo,說是JDK的bug,昨天在JVM的一個群里又有朋友發了,覺得挺有意思,分享給大家,希望大家升級JDK的版本的時候注意下是否存在這樣的代碼,如果存在記得立馬改過來。
輸出比較有意思,在JDK9以前,只輸出一個evaluated,但是JDK9以后的版本卻會輸出兩個evaluated,大家可以測試一下。
猜想
看到這個現象,大家都開始猜測了
首先,到底是編譯期問題還是運行時問題?這個好驗證,我們用JDK8編譯的class分別跑在JDK8和JDK10上,看是不是也有類似的現象。
其次,如果是編譯期問題,那到底差異在哪里,從結論看,用JDK10編譯的字節碼,test方法肯定能執行兩次。
大家驗證下來發現***種情況沒發生類似的問題了,那基本確定是第二種情況,那接下來簡單分析下。
簡單分析
驗證字節碼,我們都是通過javap去看的,javap -verbose JavacEvalBug,兩個版本下我們分別看到下面的字節碼
JDK8編譯的字節碼
其實基本相當于如下的邏輯
JDK10編譯的字節碼
粗看已經比較明了了,在JDK10編譯的字節碼里我們確實看到執行了兩次test方法,那就和結論比較匹配了。
這個Bug已經有人匯報給Oracle了,https://bugs.openjdk.java.net/browse/JDK-8204322,大家可以關注下進度,點擊原文可以進入BUG鏈接。
思維發散
上面其實都是涉及到了字符串拼接,JDK9以前用的是StringBuilder來拼接的,而JDK9開始使用了invokeDynamic指令,可以動態指定要調用的方法,而不是一開始就編譯好的,這個展開來講就比較長了,有興趣的可以網上找點資料了解一下,我有時間也可以專門寫篇相關的文章,只是感覺對這塊有比較大興趣或者有興趣一直讀下去的的估計不會太多。
改下Demo讓你再驚喜一下
如果上面的Demo改一下,把數組變成int數組
此時你再試試?
【本文是51CTO專欄作者李嘉鵬的原創文章,轉載請通過微信公眾號(你假笨,id:lovestblog)聯系作者本人獲取授權】