当前位置: 首页 > 面试题库 >

Lambda表达式如何在Java字节码中转换

宗政浩慨
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表达式声明的位置,具有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命令以检查类的字节码时,在字节码中没有针对lambda的静态方法。

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扩展?

问题答案:

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


 类似资料:
  • 我试图创建一个使用Java的lambda表达式的示例,我使用的是官方的JDK8。我的例子运行成功。但是当我试图检查编译器如何将lambda表达式翻译成字节代码时,这让我有些困惑。下面是我的示例的代码:- 在本文中,他们讨论了编译器如何将lambda表达式转换为字节码。根据本文将lambda表达式转换为方法以及lambda表达式声明的位置,有lambda方法的引用。下面的例子在文章中: 我的例子运行

  • 我还在尝试理解lambda表达式。 我想将这个lambda表达式转换为“普通”表达式: 你们有主意吗? 提前谢谢。

  • 我有一个简单的行星名称数组,我想反转添加到数组中的每个名称(而不是字符串顺序)。 我仍在努力使用lambda语法: 目前我得到: 这条线上有多个标记 类型中的方法不适用于参数 类型不匹配:无法从转换为 谢谢大家的建议。。。asList让我接近了。我仍然没有正确分类。 所以我需要找到一种方法,使array.sort工作,因为这是任务(array.sort和lambda它)。 我已经打电话给老师要求澄

  • 问题内容: 我想了一下,想到了一个有趣的问题,假设我们有一个配置(输入)文件,其中: 此外,我们还有s 的列表: 有没有办法将s(等)转换为代表lambda表达式的s?然后可以用作: 我将如何编写这样的方法? 我可以从JDK / JRE中重用吗? 我需要自己编写所有内容吗? 是否有可能将范围缩小到仅捕获lambda的其他内容? 问题答案: 马可对这个问题的评论是正确的。您无法从文件中读取裸Java

  • 本文向大家介绍Java中如何调试Lambda表达式,包括了Java中如何调试Lambda表达式的使用技巧和注意事项,需要的朋友参考一下 Lambda表达式由两部分组成,一个是参数,另一个是代码或表达式。 这两个部分由箭头运算符“->”分隔。 我们可以使用NetBeans,IntelliJ和Eclipse等不同的IDE来调试Java中的lambda表达式。 始终可以创建多行lambda表达式,并使用

  • 问题内容: 我正在研究使用Beanshell env进行产品自定义挂钩的产品(在Tomcat中运行的Sailpoint IdentityIQ)。我想编写一些代码来解析大型csv文件,并希望利用Java 8 Streams。但是我面对Beanshell env引发错误的问题,尽管我们正在使用Java 8,但无法识别Lambda表达式 有什么方法可以告诉beanshell识别lambda或代码中的转义