【发布时间】:2012-05-26 16:00:03
【问题描述】:
当使用Java编译器(javac)时,我们可以指定两种兼容性。一个使用-source,另一个使用-target。这两者有什么区别?
例如,-source 1.5 和 -target 1.6?
另外,是否存在我们使用不同的源和目标兼容级别的情况?
【问题讨论】:
标签: java compilation javac backwards-compatibility
当使用Java编译器(javac)时,我们可以指定两种兼容性。一个使用-source,另一个使用-target。这两者有什么区别?
例如,-source 1.5 和 -target 1.6?
另外,是否存在我们使用不同的源和目标兼容级别的情况?
【问题讨论】:
标签: java compilation javac backwards-compatibility
来自javac docs:
-source 指定接受的源代码版本。
-target 生成以指定 VM 版本为目标的类文件。类文件将在指定的目标和更高版本上运行,但不会在 VM 的早期版本上运行。
在你的例子中:
-source 1.5 and -target 1.6
这将用于确保源代码与 JDK 1.5 兼容,但应生成用于 JDK 1.6 及更高版本的类文件。
为什么你会这样做是另一回事。
【讨论】:
javac 不支持所有组合。我实际上也有一个用例。在 Java 6 中,JAX-WS 是内置的,所以我希望有一个解决方案可以在纯 Java 6 上运行,而不需要额外的库。然后,该解决方案需要一些客户在 Java 5 JVM(以及附带的 JAX-WS)上可执行,并且 @Override 语法发生了更改,因此 Java 5 javac 无法立即编译它。 (这是前 maven,今天可能更容易做到)
-bootclasspath,如this answer 中所述。
-source 表示您的源代码的合规级别:您是否使用注释?那么你至少需要1.5;你在接口实现上使用@override,你需要1.6等
-target 指定您希望能够在哪个 Java 版本上运行您的类。您可以使用 Java SE 7 编译器并编译以在 Java SE 1.5 上运行。
【讨论】:
这对于生成使用旧版本 Java 的 jar 文件非常有用。 我相信到目前为止所有的 JDK 都能够执行旧版本,所以没有真正的理由让目标大于源。
然而,将target 设置为例如使用 1.7 JDK 时为 1.6。
我不确定,但我相信它可以在某些情况下使用 1.7 编译器将 1.7 java 代码编译为 1.6 jar,例如表达式
ArrayList<Integer> foo = new ArrayList<>();
仅在 1.7+ 源版本中有效的应编译为 1.6 兼容字节码。但我还没有验证编译器是否真的会这样做。 不幸的是,这似乎没有在实践中实现。
【讨论】:
-target 1.6 的唯一原因是运行代码的JVM 是1.6。