编译的Java 8 lambda表达式是否向后兼容早期版本的Java运行时?

为了减少由匿名类型的大量实例化引起的混乱,我正在探索利用Java 8 lambdas的可能性。

在生产环境中使用Java 8和lambdas之前的一个重要考虑因素是,使用lambda表达式的JDK8编译代码是否可以在早期版本的Java运行时上执行。 我特别感兴趣的是JRE6和JRE7作为目标平台。

一方面,我理解lambdas只是包含一个方法的匿名类实例化的语法糖。 另一方面,我不确定这种等价意味着为每个生成的字节码在JRE8以外的JVM版本中是相同的和/或兼容的。

例如,给定单方法接口:

public interface Action { public void perform(T argument); } 

以下两个片段在function上是等效的:

使用lambda:

 final Action y = i -> System.out.println(i); 

使用匿名类实例:

 final Action y = new Action() { @Override public void perform(final String i) { System.out.println(i); } }; 

我的具体问题是两种结构的语义等价是否扩展到其编译表示的等价性。 此外,如果它们确实等价地编译,那么这个等价是否表明lambda表达式的编译forms可以托管在早期版本的Java运行时而不进行修改?

通常,Javac编译器不可能使用高于目标JVM级别的源级别。 因此答案是否定的。

正式没有,但对于非正式的解决方案,你应该看看Retrolambda项目。 它不会向后移植Collection API更改,但它可以为您处理lambda表达式(和方法引用)。

我不相信 – 字节码版本是不同的(52我认为)和lambda使用invokedynamic而不是被翻译成匿名类。

Java 8在接口中引入了默认方法实现的新概念。 添加此function是为了向后兼容,以便可以使用旧接口来利用Java 8的lambda表达式function。例如,“List”或“Collection”接口没有“forEach”方法声明。 因此,添加此类方法将简单地破坏集合框架实现。 Java 8引入了默认方法,因此List / Collection接口可以具有forEach方法的默认实现,而实现这些接口的类不需要实现相同的方法。

 public interface vehicle { default void print(){ System.out.println("I am a vehicle!"); } }