我已经看到了哪些 JDK 的发行版可以运行 `javac -source 1.6 -target 1.5` 中讨论的编译选项?. 我了解源和目标的各个选项。我不明白为什么源版本高于目标版本。为旧目标编译代码是有意义的。但是在那种情况下,我们为什么不使用 -source 我们希望能够运行的最旧目标
4 回答
- source:您的源代码编译所需的版本。
- 目标:您要支持的最旧的 JRE 版本。
确保还设置 bootclasspath 以确保您的程序可以在较旧的 VM 上运行。
从javac
文档中:
交叉编译示例
以下示例使用 javac 编译将在 1.6 VM 上运行的代码。
C\:>javac -source 1.6 -target 1.6 -bootclasspath C:\jdk1.6.0\lib\rt.jar -extdirs "" OldCode.java
该
-source 1.6
选项指定使用 Java 编程语言的 1.6(或 6)版本来编译OldCode.java
. option-target 1.6
选项确保生成的类文件与 1.6 VM 兼容。请注意,在大多数情况下,-target
期权的价值就是期权的价值-source
;在此示例中,您可以省略该-target
选项。您必须指定
-bootclasspath
选项以指定引导类(rt.jar
库)的正确版本。如果不是,编译器会生成以下警告:C:\>javac -source 1.6 OldCode.java warning: [options] bootstrap class path not set in conjunction with -source 1.6
如果您没有指定正确的引导类版本,编译器将使用旧的语言规则(在本例中,它将使用 Java 编程语言的 1.6 版)与新的引导类相结合,这可能会导致类文件不要在较旧的平台(在本例中为 Java SE 6)上工作,因为可以包含对不存在的方法的引用。
Java 是向后兼容的。您使用-source选项指定用于编译的 java 版本,并使用-target选项指定要支持的最低 java 版本。例如。如果我指定 1.4 的目标,那么我的程序将无法在 java 1.3 或更低版本上运行。有关更多信息,请参阅以下 javac文档。特别是关于交叉编译选项的部分
Peter Tseng 确实提到了很多在编译过程中要记住的关键点。事实上,即使我曾经遇到过类似的问题,也想分享许多问题的根本原因。
我有一个源代码必须编译并使其兼容 (-source & -target) Java '1.8'。代码本身有
- 很多商标符号,因此我最终得到了无法识别的字符(我不得不调整 IntelliJ Idea 的编码设置)
java.sql.*
包的很多变化- 大量第三方库的使用。免除我解释那里调试的困难和等等等等的恐惧。
经过某些更改后,我最终得到了一个运行相同数量的 JUnit 测试用例的代码。最后我碰到了一个java.lang.VerifyError
。当我了解到当我在不同的库/环境中编译和运行代码时会发生这种错误时,我感到很震惊(事实并非如此)。
我几乎错过的是,为了纪念测试必须在隔离环境中运行这一事实,Junit 及其测试用例在单独的分叉 VM 中执行
<target name="runJunit">
<junit printonsummary="on"
haltonfailure="off"
fork="true"
forkmode="once">
<formatter />
<batchtest />
<classpath />
</junit>
</target>
这显然将作为一个单独的进程跨越,并在执行中作为一个独立的应用程序。尽管 IDE 同步跨越两个进程,但 JVM 几乎是隔离的。
在 Java 1.7 之后,Oracle 引入了更严格的验证并稍微改变了类格式——包含一个堆栈映射,用于验证代码是否正确。我看到的异常是因为某些方法没有有效的堆栈映射。我最终尝试包含许多 JVM 选项来调整设置,但徒劳无功。
<jvmarg value="bootclasspath:{env.JAVA_HOME}\jre\bin\rt.jar" prefix="-X"/>
没有任何效果。唯一的解决方法是包括
<jvmarg value=":UseSplitVerifier" prefix="-XX"/>
在 Java 1.7 中只允许名义上的字节码验证。由于这是在 Java 1.8 中取消的,唯一的选择是使用
<jvmarg value="-noverify"/>
JDK1.8 将不再支持 -source 和 -target 小于 1.6
"c:\Program Files\Java\jdk1.8.0_121\bin\javac.exe" -source 1.3 HelloWorld.java
warning: [options] bootstrap class path not set in conjunction with -source 1.3
warning: [options] source value 1.3 is obsolete and will be removed in a future release
warning: [options] target value 1.4 is obsolete and will be removed in a future release
warning: [options] To suppress warnings about obsolete options, use -Xlint:-options.
4 warnings