当前位置: 首页 > 知识库问答 >
问题:

你能用Java8编译一个类,然后在Java7中使用它吗?[副本]

卫弘懿
2023-03-14

你能用Java8编译一个类,然后在Java7中使用它吗?

如你所见,有一些自相矛盾的答案…那么,真相是什么呢?;-)

共有1个答案

相德宇
2023-03-14

在使用Java8 javac编译时,可以使用-source1.7-target1.7来制作在Java7上工作的.类。但是,您没有得到Java8特性,比如lambdas,因为您还必须使用1.7作为源值。

但这还不是故事的结尾。在这个答案中解释了实际上并没有新的JVM指令,所以这应该是可能的。在这个答案中,介绍了工具retrolambda,它可以用来在较旧的JVM上运行Java8代码。作者声称不需要编译步骤,只需要一个java代理来转换类。他的解决方案只处理lambda,而不处理任何其他特性。当然,这不会给您带来Java8附带的新API或其他改进,但至少会使您的要求成为可能。一些新的API也经过了非官方的备份,即java.util.Stream和java.time。

如果我们处于Java8之前的时代,即使javac不支持-source1.8-target1.7,您仍然可以使用编译器API来完成同样的操作。此外,Eclipse编译器也能够做到这一点,使用上述两个选项之一的ant和maven任务也是如此(compiler-plugin默认使用javac)。这似乎不再那么简单了,因为使用其他编译器还需要lambdas等特性的实现,编译器API也会抛出与其他编译器相同的“javac:source Release1.8 requires target Release1.8”(javac:source Release1.8 requires target Release1.8)。

对于感兴趣的人,下面是使用Eclipse编译器&Maven和计算器示例代码进行的操作:

pom.xml:

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>fi.eis.applications.java8</groupId>
  <artifactId>calculator</artifactId>
  <version>1.0-SNAPSHOT</version>
  <build>
    <plugins>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.3</version>
        <configuration>
          <source>1.8</source>
          <target>1.7</target>
          <compilerId>eclipse</compilerId>
        </configuration>
        <dependencies>
          <dependency>
            <groupId>org.codehaus.plexus</groupId>
            <artifactId>plexus-compiler-eclipse</artifactId>
            <version>2.6</version>
          </dependency>
        </dependencies>
      </plugin>
    </plugins>
  </build>
</project>

在Windows上执行:

>mvn clean compile
[..snip..]
[INFO] BUILD SUCCESS
>cd target\classes

>"%JAVA_HOME%\bin\java.exe" Calculator
Exception in thread "main" java.lang.NoClassDefFoundError: java/lang/invoke/LambdaMetafactory
        at Calculator.main(Calculator.java:16)
Caused by: java.lang.ClassNotFoundException: java.lang.invoke.LambdaMetafactory
        at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        ... 1 more

因此,需要将这些类作为第三方库在纯java中实现才能使其正常工作。

 类似资料:
  • 我有一个jar文件在某些特性只属于(用于ex lambda表达式),所以它是在中编译的。同一jar具有属于和的一些特性。现在,我希望当用户在中运行这个jar时,相关类应该可以工作,因为他/她只想要在上工作的功能。如果他/她想要与Java8相关的功能,他将使用运行它。

  • 我有Java8SDK和运行时,以及一个只使用Java7个功能的项目。我想知道我是否可以设置intellij来构建一个Java-7级的jar,从命令行肯定可以做到这一点? 到目前为止,我已经尝试过简单地将项目语言级别设置为7作为实验,但这显然是不够的,也不是我真正需要的。 我在SO上也看到过这个问题:"Intellij IDEA使用java7编译器编译,当我已经将其配置为使用Java6",但我的项目

  • 我一定是个反Maven的人,因为每次我尝试使用它时,我都会花很多时间挣扎,然后就放弃了。我的最新情况是,我不能编译Java7源代码,尽管有1.7的JDK。 以下是的输出。有趣的是,当我使用Maven 3.0.4时,错误消息是而不是使用Maven 3.2.1的 正如您所看到的,我使用的是Maven的最新版本,Maven使用的是Java1.7。 我认为脚本正在添加,因为我的环境变量没有指定它。 我正在

  • Java8引入了重要的新语言特性,如lambda表达式。 语言中的这些变化是否伴随着编译字节码中的重大变化,从而阻止它在不使用某些反向翻译器的情况下在Java7虚拟机上运行?

  • 我试图使用wsgen生成wsdl文件。如果我的webservice类扩展另一个类,我得到一个错误,但如果我删除扩展它的工作。这是错误消息: 另外,wsgen-完整版本: 请注意,我只有在使用Java8时才会出现这个问题。但是当我使用Java7和wsgen版本时,同样的代码可以工作: 下面是更多的细节以及如何复制它:我正在使用Java8,我有三个文件: basewebservice.java: 包w

  • 如果第一点是真的,Java8应用程序将在Java7服务器支持上部署和执行?比如Tomcat 8还是Wildfly?