javac源和目标选项

时间:2013-03-19 06:33:32

标签: java javac

我已经看到了Which JDK's distributions can run `javac -source 1.6 -target 1.5`?中讨论的编译选项。我理解源和目标的各个选项。我不明白为什么源版本高于目标版本。编译旧目标的代码是有道理的。但在这种情况下,为什么我们不使用我们希望能够在其上运行的最老目标的源?

4 个答案:

答案 0 :(得分:21)

Java向后兼容。您可以使用 -source 选项指定用于编译的java版本,并使用 -target 选项指定要支持的最低java版本。例如。如果我指定1.4的目标,那么我的程序将无法在java 1.3或更低版本上运行。有关详细信息,请参阅以下javac documentation。特别是关于交叉编译选项

的部分

答案 1 :(得分:21)

  • source:源代码需要编译的版本。
  • target:您要支持的最旧的JRE版本。

请务必设置bootclasspath以确保您的程序可以在较旧的VM上运行。


来自javac documentation

  

交叉编译示例

     

以下示例使用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。选项-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
     

如果没有指定正确版本的bootstrap类,编译器将使用旧的语言规则(在本例中,它将使用Java编程语言的1.6版本)与新的bootstrap类结合使用,这可能导致在旧平台上不起作用的类文件(在本例中为Java SE 6),因为可以包含对不存在的方法的引用。

答案 2 :(得分:2)

Peter Tseng确实提到了编译过程中要记住的许多要点。事实上,即使我在某个时候遇到过类似的问题,也想分享许多问题的根本原因。

我有一个必须编译的源代码。使它兼容(-source& -target) Java' 1.8' 。代码本身有

  1. 很多商标符号因此我最终得到了无法识别的字符(我不得不调整IntelliJ Idea的编码设置)
  2. java.sql.* package
  3. 的大量更改
  4. 许多第三方库的使用。让我害怕解释那里的调试困难,等等等等。
  5. 经过一些更改后,我最终得到了一个代码,该代码具有相同数量的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"/>
    

答案 3 :(得分:0)

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