当前位置: 首页 > 知识库问答 >
问题:

如何用Java字节码翻译Lambda表达式

杭令
2023-03-14

我试图创建一个使用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));
    }
}

在本文中,他们讨论了编译器如何将lambda表达式转换为字节码。根据本文将lambda表达式转换为static方法以及lambda表达式声明的位置,有lambdastatic方法的引用。下面的例子在文章中:

//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[]);
}

在泛型的情况下,bridge方法是由编译器创建的,我们还将使用javap命令检查该方法,但在lambdas的情况下没有statice方法。这篇文章发表于2012年,Java八号于2014年3月发射。所以我对Lambda的跨国有一些疑问:

  1. 在本文发布之后,JDK8中是否有任何用于lambda的新实现,或者我会做一些错误的事情来检查lambda方法?
  2. 编译器如何处理lambda表达式?
  3. JVM如何调用lambda expression?

共有1个答案

涂浩皛
2023-03-14

使用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;
}
 类似资料:
  • 问题内容: 在C#中,您可以将lambda表达式包含在表达式树对象中,然后可能对其进行解析。我想知道在Java中这是否还可以吗? 我正在寻找的是做这样的事情: 然后,应该基于指定为lambda的谓词以某种方式将该查询转换为以下RESTful API请求: 然后将结果返回给客户端。知道这在Java中是否可行? 问题答案: 是的,有可能。我制作了一个库来做到这一点:JaQue

  • 问题内容: 我正在尝试使用Java中的lambda表达式创建一个示例,而我正在使用官方JDK8。我的示例已成功运行。但是当我尝试检查编译器如何将lambda表达式转换为字节码时,这让我有些困惑。以下是我的示例代码:- 在这个文章,他们关于如何编译的lambda表达式转换成字节码讨论。根据该文档,lambda表达式转换为方法以及lambda表达式声明的位置,具有lambda 方法的引用。以下示例在文

  • 问题内容: 我有以下代码: 当我通过main方法运行它时,它运行良好,但是当我尝试对其进行编译时,抛出以下错误: 我正在使用Eclipse IDE,并尝试通过命令行进行编译。 问题答案: 默认情况下,使用Java 5来编译类。引用其文档: 还要注意,当前的默认源设置是1.5,默认目标设置是1.5,与运行Maven的JDK无关。如果要更改这些默认值,则应按照设置Java编译器的- source和-t

  • 问题内容: 考虑以下Java 8代码段。 什么是越来越编译? 我知道Lambda并没有实现为匿名内部类。但是,因此接口必须在生成某种对象,但是尚不清楚在生成哪种对象。 Java 8中是否存在某种表示lambda表达式的新型对象? 更新 这是经过反编译的程序,该程序已使用eclipse java 8编译器编译,当您打开类文件时,以下输出来自eclipse。 看起来lambda表达式已变成包含lamb

  • 问题内容: Java8中添加了Lambda表达式。我想理解为什么这很重要。对于尚未接触函数式编程习惯的Java程序员意味着什么?这是否意味着我可以编写出性能更好的代码或可大规模扩展的代码,还是只会使代码的详细程度降低。或全部。 问题答案: Oracle已经提供了有关该主题的教程。它列出了几个很好的用例。 在找到链接之前,我要说的是lambda表达式可让您将“函数”传递给代码。因此,您可以更轻松地编

  • 主要内容:函数式接口Lambda 表达式(Lambda expression)是一个匿名函数,基于数学中的λ演算得名,也可称为 闭包(Closure)。现在很多语言都支持 Lambda 表达式,如 C++、 C#、 Java、 Python 和 JavaScript 等。 Lambda 表达式是推动 Java 8 发布的重要新特性,它允许把函数作为一个方法的参数(函数作为参数传递进方法中),下面通过例 1 来理解 L