編譯不同版本的 Java
Java 程式語言(及其執行時)自其首次公開發布以來發布以來經歷了許多變化。這些變化包括:
- Java 程式語言語法和語義的變化
- Java 標準類庫提供的 API 的更改。
- Java(位元組碼)指令集和類檔案格式的更改。
除了極少數例外(例如 enum
關鍵字,對某些內部類的更改等),這些更改是向後相容的。
- 使用較舊版本的 Java 工具鏈編譯的 Java 程式將在較新版本的 Java 平臺上執行,無需重新編譯。
- 使用舊版 Java 編寫的 Java 程式將使用新的 Java 編譯器成功編譯。
使用較新的編譯器編譯舊 Java
如果你需要(重新)在較新的 Java 平臺上編譯較舊的 Java 程式碼以在較新的平臺上執行,則通常不需要提供任何特殊的編譯標誌。在少數情況下(例如,如果你使用 enum
作為識別符號),你可以使用 -source
選項來禁用新語法。例如,給定以下類:
public class OldSyntax {
private static int enum; // invalid in Java 5 or later
}
使用 Java 5 編譯器(或更高版本)編譯類需要以下內容:
$ javac -source 1.4 OldSyntax.java
編譯舊的執行平臺
如果需要編譯 Java 以在較舊的 Java 平臺上執行,最簡單的方法是為需要支援的最舊版本安裝 JDK,並在構建中使用該 JDK 的編譯器。
你也可以使用較新的 Java 編譯器進行編譯,但這很複雜。首先,必須滿足一些重要的先決條件:
- 你編譯的程式碼不得使用你所定位的 Java 版本中不可用的 Java 語言結構。
- 程式碼不能依賴於舊平臺中不可用的標準 Java 類,欄位,方法等。
- 程式碼所依賴的第三方庫也必須為較舊的平臺構建,並在編譯時和執行時可用。
在滿足前提條件的情況下,你可以使用 -target
選項重新編譯舊平臺的程式碼。例如,
$ javac -target 1.4 SomeClass.java
將編譯上面的類以生成與 Java 1.4 或更高版本 JVM 相容的位元組碼。 (實際上,-source
選項意味著相容的 -target
,因此 javac -source 1.4 ...
會產生相同的效果。在 Oracle 文件中描述了 -source
和 -target
之間的關係。)
話雖如此,如果你只是使用 -target
或 -source
,你仍然會編譯編譯器的 JDK 提供的標準類庫。如果你不小心,最終可能會得到具有正確位元組碼版本的類,但依賴於不可用的 API。解決方案是使用 -bootclasspath
選項。例如:
$ javac -target 1.4 --bootclasspath path/to/java1.4/rt.jar SomeClass.java
將針對另一組執行時庫進行編譯。如果正在編譯的類具有(意外)依賴於較新的庫,則會給出編譯錯誤。