【问题标题】:How Lambda Expressions Are Translate In Java Byte CodeLambda 表达式如何在 Java 字节码中翻译
【发布时间】:2014-06-01 17:32:27
【问题描述】:

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

public class LambdaTest {
    public Integer lambdaBinaryOpertor(BinaryOperator<Integer> binaryOperator) {
        return binaryOperator.apply(60, 72);
    }

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

Article 中,他们讨论了编译器如何将 lambda 表达式转换为字节码。根据该文档将 lambda 表达式转换为 static 方法和 lambda 表达式声明的位置,参考 lambda static 方法。以下示例在文章中:

//Source code
class A {
    public void foo() {
        List<String> list = ...
        list.forEach( s -> { System.out.println(s); } );
    }
} 

//After compile above code "translate code " 
class A {
    public void foo() {
        List<String> 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 <java.lang.Integer>);
public static void main(java.lang.String[]);
}

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

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

【问题讨论】:

    标签: java lambda jvm java-8 compiler-theory


    【解决方案1】:

    使用 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;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-05
      相关资源
      最近更新 更多