我已经看到了哪些 JDK 的发行版可以运行 `javac -source 1.6 -target 1.5` 中讨论的编译选项?. 我了解源和目标的各个选项。我不明白为什么源版本高于目标版本。为旧目标编译代码是有意义的。但是在那种情况下,为什么我们不使用我们希望能够运行的最旧目标的 -source
我已经看到了哪些 JDK 的发行版可以运行 `javac -source 1.6 -target 1.5` 中讨论的编译选项?. 我了解源和目标的各个选项。我不明白为什么源版本高于目标版本。为旧目标编译代码是有意义的。但是在那种情况下,为什么我们不使用我们希望能够运行的最旧目标的 -source
Java 向后兼容。您可以使用-source选项指定用于编译的 Java 版本,并使用-target选项指定要支持的最低 Java 版本。例如。如果我将目标指定为 1.4,那么我的程序将无法在 java 1.3 或更低版本上运行。有关更多信息,请参阅以下 javac文档。特别是关于交叉编译选项的部分
Peter Tseng 确实提到了很多编译过程中要记住的关键点。事实上,即使我以前也遇到过类似的问题,并想分享许多问题的根本原因。
我有一个源代码,必须编译并使其兼容 (-source & -target) Java '1.8'。代码本身有
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 将不再支持低于 1.6 的 -source 和 -target
"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
一定还要设置 bootclasspath 以确保您的程序可以在较旧的 VM 上运行。
从
javac
文档: