有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

编译如果Java6工件是用Java6、7或8编译的,这有关系吗?

我已经配置了一个持续集成工具(Travis CI)来在每次提交时运行,它在以下JDK上构建我的Java 6项目:

  • oraclejdk8
  • Oracle JDK 7
  • 打开jdk7
  • 打开jdk6

现在Travis CI还不支持在所有任务完成后上传所创建工件的任务,所以我使用了一种解决方法

我的问题是,解决方案将尝试将创建为last的工件上载到Sonatype快照存储库

这意味着一次它将上传一个由OpenJDK6编译的快照,另一次由OpenJDK7编译,等等

这有关系吗?Java6客户机可以使用任何Java6+JDK编译的Java6代码吗?我们已经知道代码(看起来)做了它想要做的事情,因为它已经编译并且测试已经通过了

Java 6代码可以在任何与Java 6兼容的JRE和Android上运行


共 (2) 个答案

  1. # 1 楼答案

    否。-但是您必须指定-target

    当Java编译类时,它为目标Java JRE编译类。有关参考,请参见javac option for javac 1.7(和for Java8 here

    -target version
        Generate class files that target a specified version of the VM.
        Class files will run on the specified target and on later versions,
        but not on earlier versions of the VM.
        Valid targets are 1.1, 1.2, 1.3, 1.4, 1.5 (also 5), 1.6 (also 6), and 1.7 (also 7).
    
    The default for -target depends on the value of -source:
    
        If -source is not specified, the value of -target is 1.7
        If -source is 1.2, the value of -target is 1.4
        If -source is 1.3, the value of -target is 1.4
        If -source is 1.5, the value of -target is 1.7
        If -source is 1.6, the value of -target is 1.7
        For all other values of -source, the value of -target is the value of -source.
    

    因此,使用Java8 javac编译的代码,目标为1.7,只有在代码不使用Java8或更高版本中可用的任何功能时,才可以在Java7 JRE上运行

    因此,在您的例子中,使用Java8JDK编译的代码,如果没有javac命令的-target参数,甚至无法在Java6上加载。错误将是:UnsupportedClassVersionError

  2. # 2 楼答案

    如果您在Java 6和Java 8(定义目标版本)中成功构建了代码,那么您可以将代码提供给其他人,并且只需要他们拥有Java 6+(也设置了目标版本),它就可以在任何Java 6或更高版本上工作

    为此,需要设置-target 1.6 -source 1.6或在maven-compiler-plugin中指定版本。(我强烈建议您使用构建工具)

    在maven你会

    <project>
      [...]
      <build>
        [...]
        <plugins>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.2</version>
            <configuration>
              <source>1.6</source>
              <target>1.6</target>
            </configuration>
          </plugin>
        </plugins>
        [...]
      </build>
      [...]
    </project>
    

    任何使用您的构建的人都将创建一个JAR,其字节码可在Java 6+上运行


    在Java 8中编译Java 6的字节码时,可以在Java 6+上使用

    您发现的问题是,与Java6相比,Java8在JDK中有更多的类和方法。这意味着Java8编译器将乐于编译Java6,它使用Java8中可用但Java6中不可用的类、方法或字段

    在编译代码时,可以告诉Java 8编译器使用Java 6库,但更简单的解决方案是使用Java 6编译器,或者您可以假设这不会发生,或者您有另一种方法来检测Java 6代码仅使用Java 6可用的库

    第三方库也可能存在同样的问题。您可以根据在Java8中工作的第三方库的版本进行编译,但对于Java6,您必须使用旧版本的库(或者可能不存在)

    另一个问题是Java8修复了Java6允许的编译器中的一些错误。这些修复非常奇特,您必须编写非标准Java代码(由于编译器中存在错误,Java 6允许编写非标准Java代码)

    Javadoc在默认情况下会抱怨不支持Javadoc,甚至在Java6的Javadoc通过时无法构建