编译不同版本的 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
将针对另一组运行时库进行编译。如果正在编译的类具有(意外)依赖于较新的库,则会给出编译错误。