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

时间:2014-03-22 01:23:24

标签: java lambda backwards-compatibility java-8

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

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

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

例如,给定单方法接口:

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

以下两个片段在功能上是&#34;当量:

使用lambda:

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

使用匿名类实例:

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

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

4 个答案:

答案 0 :(得分:8)

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

答案 1 :(得分:7)

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

答案 2 :(得分:3)

我不相信 - 字节码版本不同(52我想)和lambda使用invokedynamic而不会被翻译成匿名类..

答案 3 :(得分:0)

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

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