Lambda表达式如何在Java字节代码中进行翻译

我试图在java中使用lambda表达式创建一个示例,我正在使用官方JDK8。 我的例子运行成功。 但是当我试图检查编译器如何将lambda表达式转换为字节代码时,这让我有些困惑。以下是我的例子的代码: –

public class LambdaTest { public Integer lambdaBinaryOpertor(BinaryOperator binaryOperator) { return binaryOperator.apply(60, 72); } public static void main(String[] args) { LambdaTest test = new LambdaTest(); BinaryOperator binaryOperator = (a, b) -> a*b; System.out.println("Additon using Lambda BinaryOperator: "+test.lambdaBinaryOpertor(binaryOperator)); } } 

在本文中,他们讨论了编译器如何将lambda表达式转换为字节代码。 根据这个文档,lambda表达式转换为static方法和lambda表达式声明的位置,具有lambda static方法的引用。 以下示例位于文章中:

 //Source code class A { public void foo() { List list = ... list.forEach( s -> { System.out.println(s); } ); } } //After compile above code "translate code " class A { public void foo() { List list = ... list.forEach( [lambda for lambda$1 as Block] ); } static void lambda$1(String s) { System.out.println(s); } } 

我的例子运行正常并给我们适当的结果。 但是当我试图运行javap命令来检查类的字节代码时,字节代码中没有lambdas的静态方法。

 c:\>javap LambdaTest Compiled from "LambdaTest.java" public class LambdaTest { public LambdaTest(); public java.lang.Integer lambdaBinaryOpertor(java.util.function.BinaryOperator ); public static void main(java.lang.String[]); } 

在generics的情况下,桥接方法由编译器创建,我们也将使用javap命令检查此方法,但在lambdas的情况下,没有static方法。 这篇文章发表于2012年,java 8于2014年3月推出。所以我对lambda的跨国有一些疑问:

  1. 在本文发布之后,JDK 8中是否有任何新的实现用于lambda,或者我会检查lambda方法有什么问题?
  2. 编译器如何处理lambda表达式?
  3. JVM如何调用lambda exression?

使用javap附加参数打印有关类的完整信息: javap -v -p -s -c

对于您的示例,lambda的源代码将是:

 private static java.lang.Integer lambda$main$0(java.lang.Integer, java.lang.Integer); descriptor: (Ljava/lang/Integer;Ljava/lang/Integer;)Ljava/lang/Integer; flags: ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC Code: stack=2, locals=2, args_size=2 0: aload_0 1: invokevirtual #17 // Method java/lang/Integer.intValue:()I 4: aload_1 5: invokevirtual #17 // Method java/lang/Integer.intValue:()I 8: imul 9: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; 12: areturn LineNumberTable: line 10: 0 LocalVariableTable: Start Length Slot Name Signature 0 13 0 a Ljava/lang/Integer; 0 13 1 b Ljava/lang/Integer; }