可以编译Java8代码以在Java7JVM上运行吗?

可以编译Java8代码以在Java7JVM上运行吗?,java,jvm,compatibility,java-7,java-8,Java,Jvm,Compatibility,Java 7,Java 8,Java8引入了重要的新语言特性,如lambda表达式 语言中的这些变化是否伴随着编译字节码中的重大变化,而这些变化会阻止它在Java 7虚拟机上运行而不使用一些Retro Translator?据我所知,JDK 8中的这些变化都不需要添加新的字节码。lambda工具的一部分是使用invokeDynamic(已经存在于jdk7中)完成的。因此,从JVM指令集的角度来看,没有什么可以使代码库不兼容。不过,有很多与API相关的和编译器的改进,可能会使JDK 8中的代码难以在以前的JDK下编译/运行(

Java8引入了重要的新语言特性,如lambda表达式


语言中的这些变化是否伴随着编译字节码中的重大变化,而这些变化会阻止它在Java 7虚拟机上运行而不使用一些Retro Translator?

据我所知,JDK 8中的这些变化都不需要添加新的字节码。lambda工具的一部分是使用
invokeDynamic
(已经存在于jdk7中)完成的。因此,从JVM指令集的角度来看,没有什么可以使代码库不兼容。不过,有很多与API相关的和编译器的改进,可能会使JDK 8中的代码难以在以前的JDK下编译/运行(但我没有尝试过)

以下参考资料可能有助于丰富对lambda相关变更的理解


这些详细解释了如何在引擎盖下安装仪器。也许您可以在那里找到问题的答案。

不,在源代码中使用1.8功能要求您以1.8虚拟机为目标。我刚刚尝试了新的Java 8版本,并尝试使用
-target 1.7-source 1.8
进行编译,但编译器拒绝了:

$ javac Test -source 1.8 -target 1.7
javac: source release 1.8 requires target release 1.8

如果您愿意使用“retrotranslator”,请尝试Esko Luontola出色的Retrolambda:

默认方法需要对字节码和JVM进行这样的更改,这在Java 7上是不可能做到的。Java7及以下版本的字节码验证器将拒绝与方法体的接口(静态初始化器方法除外)。尝试在调用端用静态方法模拟默认方法不会产生相同的结果,因为默认方法可以在子类中重写。对后端口默认方法的支持有限,但它永远不能完全后端口,因为它确实需要新的JVM特性

如果必要的API类存在的话,Lambdas可以按原样在Java7上运行。invokedynamic指令存在于Java7上,但是可以实现lambdas,以便在编译时生成lambda类(早期的JDK8构建就是这样做的),在这种情况下,它可以在任何Java版本上工作。(Oracle决定将InvokedDynamic用于lambda以备将来验证;也许有一天JVM将具有一流的函数,因此可以将InvokedDynamic更改为使用它们,而不是为每个lambda生成一个类,从而提高性能。)Retrolambda所做的是处理所有调用的动态指令,并用匿名类替换它们;与Java 8在运行时第一次调用lamdba InvokedDynamic时所做的相同

只是语法上的糖。它们与以前的版本是字节码兼容的。在Java7中,您只需要自己实现helper方法(例如),它隐藏了包含重复注释的容器注释的实现细节

AFAIK只在编译时存在,因此它们不需要更改字节码,因此只要更改Java 8编译类的字节码版本号就足以使它们在Java 7上工作

存在于Java 7的字节码中,因此这也是兼容的。您可以通过读取方法的字节码并查看方法调试信息中的局部变量名来访问它们。例如,Spring框架正是这样实现的,所以可能有一个库方法可以调用。因为抽象接口方法没有方法体,所以Java 7中的接口方法和Java 8中的AFAIK都不存在调试信息

主要是新的API、对热点和工具的改进。一些新API作为第三方库提供(例如和)


默认方法需要新的JVM特性,但其他语言特性不需要。如果您想使用它们,您需要用Java8编译代码,然后将字节码转换为Java5/6/7格式。至少字节码版本需要更改,javac不允许
-source 1.8-target 1.7
,因此需要一个反向转换器。

您可以执行
-source 1.7-target 1.7
,然后它将编译。但是,如果您具有Java8特有的特性,如lambdas,它将无法编译。没有新的字节码,而是新的结构。验证器会呕吐。接口就是一个很好的例子。它们现在可以包含方法。Java7验证器没有配备来处理这个问题。所有的旧字节码都被使用了,但都是以一种新的方式使用的。我想知道,拥有如此多语言功能的scala编译器是如何实现jdk5的目标jvm版本的。@MarinosAn你到底是什么意思?具有包含具体方法的特征的MI,例如
类C用B扩展A
,通过正常接口
A
B
以及伴随类
A$class
B$class
实现。类
C
只是将方法转发给静态的伴生类。Self类型根本不强制,lambda在编译时被传输到抽象的内部类中,因此带有带B的表达式的
新D也是如此。模式匹配是一组if-else结构。非本地报税表?试试lambda的抓水装置。还剩下什么?(有趣的是,我的scalac说1.6是默认值)当然,self类型等是在特殊的类属性和注释中编码的,这样scalac可以在使用已经编译的类时使用并强制执行规则。不,我认为不会。Java在台式机市场上占有很小的份额,但却牢牢掌握着这一份额。但它确实阻碍了新版本和功能的采用。我很长一段时间都不能在我编写的代码中使用Java8特性,因为我想避免人们不得不升级他们的本地Java安装?“是”意味着可以编译Java8