[英]Do Linux and Windows java compilers produce the same or different class files?
[英]Do different Java Compilers (where the vendor is different) produce different bytecode
給定相同的主要版本,比如Java 7,做不同的Java編譯器(例如,Oracle的熱點,JRockit或IBM的J9等......)將給定的java源代碼文件編譯成相同的bytcode?
掃描Java 7語言規范似乎正在討論的是語言的語義,而不是將代碼轉換為字節碼。
這個問題與不同的major.minor版本不同,給定供應商生成相同的字節碼。 這個問題已在這里得到解答 - 可能是 。
從以下答案到Java類文件的創建是否確定? 和這個問題的答案是指評論此沿側兩個答案上述問題MAJOR.MINOR 1和2 ,我收集了答案,我的問題是YES。
上述摘錄如下:
JLS留下了許多實現細節,從一個實現到另一個實現。
和
但是,JLS沒有指定從源代碼到生成的字節代碼的1:1映射,因此您不應該依賴於生成完全相同的字節代碼。
然而, 這里的評論意味着不同:
它是編譯器,即javac,使用BLAH BLAH BLAH創建代碼。 這與HotSpot無關。
這意味着給定代碼X所有javac實現(相同版本/不同供應商)必須生成相同的Y字節碼。
我不明白這是怎么回事,但我無法證實它不是(或者我認為,見上文)是正確的。
可以給出明確的答案嗎?
有兩個問題:
顯然,1的答案是肯定的。 否則,JLS必須完全指定為每個語言結構生成的字節碼。 但事實並非如此。
2的答案我不確定,雖然我聽說eclipse編譯器在某些情況下產生的代碼與javac略有不同。 應該很容易驗證。
有問題的評論實際上並不反對。 請注意,您在這里混合了兩個不同的東西:Java字節碼編譯器( javac
)和Java即時編譯器(例如HotSpot或J9)。 您通常使用一些javac實現將java源代碼轉換為java字節碼。
然后你獲取字節碼並在JVM中執行它,它使用另一個編譯器。
同樣,有兩組編譯器:
.java
到.class
) .class
文件) ( 編輯:這些都不能保證產生相同的結果(即,相同的java
文件可以產生不同的class
文件,並且當JIT完成時,相同的class
文件可以產生不同的機器代碼。))
有兩個順序編譯過程的原因是,如果將所有內容都包裝到一個編譯器中,則會丟失兩個屬性:
編譯器之間存在差異,有趣的是,一些允許的差異導致了過去的問題。
一些差異很小,例如,一些編譯器優化x=x+1
以產生與x++
相同的字節碼,而其他編譯器則不然。
其他人可能會產生更大的影響,例如標准沒有指定如何生成過去用於實現私有成員(和類似事物)的內部類訪問的合成成員的名稱(我不知道它是否在今天)。 但是用於計算默認serialVersionUID
的算法在所有類成員上使用哈希碼,甚至是合成成員。
因此,使用javac
或第一個Eclipse版本進行編譯會創建具有不兼容的serialVersionUID
的類。 今天,Eclipse對合成成員使用與javac
相同的名稱模式,並在默認情況下發出有關在Serializable
類中缺少顯式serialVersionUID
的警告。
仍然有很多自由,甚至包裝pack200
包可能會創建具有不同於原始類的字節代碼的類。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.