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

编译后的Java8Lambda表达式是否与Java运行时的早期版本向后兼容?,java,lambda,backwards-compatibility,java-8,Java,Lambda,Backwards Compatibility,Java 8,为了减少匿名类型的大量实例化造成的混乱,我正在探索利用Java8Lambdas的可能性 在生产环境中使用Java8和lambda之前,一个重要的考虑因素是使用lambda表达式的JDK8编译代码是否可以在Java运行时的早期版本上执行。我对JRE6和JRE7作为目标平台特别感兴趣 一方面,我理解lambda只是包含一个方法的匿名类的实例化的语法糖。另一方面,我不确定这种等价性是否意味着为每个生成的字节码在JRE8以外的JVM版本中是相同和/或兼容的 例如,给定单一方法接口: public int

为了减少匿名类型的大量实例化造成的混乱,我正在探索利用Java8Lambdas的可能性

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

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

例如,给定单一方法接口:

public interface Action<T> {
    public void perform(T argument);
}
公共接口操作{
公共无效执行(T参数);
}
以下两个代码段在“功能”上是等效的:

带有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);
    }
};
最终操作y=i->System.out.println(i);
匿名类实例:

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);
    }
};
最终行动y=新行动(){
@凌驾
公共作废执行(最终字符串i){
系统输出打印LN(i);
}
};

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

一般来说,Javac编译器不可能使用高于目标JVM级别的源代码级别。因此答案是否定的。

我不这么认为-字节码版本不同(我想是52),lambda使用InvokedDynamic,不会被转换成匿名类。

官方否定,但对于非官方的解决方案,您应该看看这个项目。它不支持集合API的更改,但它可以为您处理lambda表达式(和方法引用)。

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

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

Javac不支持为较旧的jvm编译较新的语言特性。所有以前的版本都是这样,Java8也是这样。请参阅:。一般来说,这是因为Javac不是唯一的编译器,所以有人可能会构建一个确实支持它的编译器。@user2864740您所指的帖子讨论了一个完全不同的问题:它声称不同版本的Javac编译器尽管设置为同一源代码,但处理代码的方式存在不一致级别。感谢您备份您的答案。除了目标JVM级别(实际上是类文件版本)之外,lambda还需要在Java 8中添加的运行时支持,而Java 7中没有。InvokedDynamic在1.7中也可用。lambda是使用方法引用实现的,这是一项新功能。可以让lambda在Java 7虚拟机上工作,但官方编译器不这样做。在我看来,最好将JRE升级到Java 8,而不是尝试使用技巧或黑客让lambda在JRE6/7上工作;这不仅是因为您可以获得Java 8功能,还因为JRE 6和7已经过时,不再从Oracle获得任何免费(安全)更新;它使用了更有效的表示形式,因此不需要匿名类。请进行良好的单元测试,并在处理过的类上运行它们。如果retrolambda中有一个bug,你应该事先知道。太好了!。这正是我想要的。我可以享受Java 8的个人LIB功能,知道如果需要,Retrolaba可以帮助为旧版本做准备:)