![](/img/trans.png)
[英]Do different Java Compilers (where the vendor is different) produce different bytecode
[英]Do different JDK Updates produce different Java byte code?
假設情景:
我有一個項目的源合規級別指定為1.5。 現在我用兩個不同的JDK編譯這個項目:首先使用JDK 6 Update 7,然后使用JDK 6 Update 20。
這兩個不同的JDK是否會生成不同的Java字節代碼,盡管它們的Update版本只有不同?
沒有什么可以阻止不同版本生成不同的字節碼,只要它符合JLS中指定的行為即可 。 JLS留下了許多實現細節,從一個實現到另一個實現。
生成的代碼通常僅在編譯器錯誤修復的情況下有所不同。
但是,JLS 沒有指定從源代碼到生成的字節代碼的1:1映射,因此您不應該依賴於生成完全相同的字節代碼。
讓我們從另一方面回答:無法保證任何兩個版本的jdk產生相同的字節代碼。 所以你可以期待一般的差異。
如果至少在某些情況下它沒有導致更改字節代碼,那么為什么在地球上有人會遇到發布更新開發工具包的麻煩? 我強烈懷疑是否有人會為了文檔更新而這樣做。
字節碼可能略有不同,但這不用擔心,因為它仍然是兼容的。
真正要執行的是取決於JIT。
例如JDK 6 Update 7的編譯器可能輸出與JDK 6 Update 20的編譯器略有不同的字節碼,但由於它是Java 6,因此類文件將完全兼容 - 您將能夠運行使用Update 20編譯的代碼更新7沒有任何問題。
在主要Java版本(例如Java 5與Java 6)之間可能存在更改,因此在較新版本上編譯的代碼將無法在舊版本上運行。 例如,對於Java 7,很可能會出現一個新指令invokedynamic 。 包含該指令的類文件將無法在較舊的Java版本上運行。
但是,更新版本之間從未進行過如此大的更改。
正如通常用於不同的編譯器一樣,它也是在Java情況下:結果必須相同,但它的到達方式可以(從字節碼的角度來看)不同,例如由於優化或類似。 JVM是基於堆棧的V機器; 以下是一個虛構的例子(我不知道jvm助記符的指令操作碼)
push 10 push 20 add
push 19 push 1 add push 10 add
這些產生相同的結果,但生成的字節碼是不同的(第一個稍微優化,第二個是“完全”未優化;第三個選項可能是push 30
因為我們添加已知(可能在編譯時)常量)。 這是一個簡單的案例,但可以輕松構建更復雜的案例。
如果使用不同的JDK版本進行編譯,我建議使用javac的target選項。 否則,您可能無法使用較舊的JDK運行jar。
您可能還想使用javac的source選項,以確保開發人員不使用在最近的JDK中添加的類/方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.