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

Java 8 lambda是否被编译为内部类,方法或其他东西?[重复]

欧阳俊捷
2023-03-14
问题内容

该文章建议,lambda 不能实现为匿名内部类(由于性能)。它给出了一个示例,可以将lambda表达式编译为类的(静态)方法。

我尝试了一个非常简单的代码段:

private void run() {
    System.out.println(this);
    giveHello(System.out::println);
}

private void giveHello(Consumer<String> consumer) {
    System.out.println(consumer);
    consumer.accept("hello");
}

输出为:

sample.Main@14ae5a5
sample.Main$$Lambda$1/168423058@4a574795
hello

因此,它不是同一实例。这也不是中央“ Lambda Factory”实例。

那么如何实现lambda?


问题答案:

假设您传递的是 实际的lambda表达式
而不是方法引用,则表达式本身将被编译为单独的合成方法。除了预期功能接口的任何形式参数(例如,String在情况下为单个Consumer<String>),它还将包含任何捕获值的参数。

在出现lambda表达式或方法引用的代码位置,将invokedynamic发出一条指令。第一次点击此指令时,会在上调用一个引导方法LambdaMetafactory。该引导方法将修复目标功能接口的实际实现,该目标函数接口委托给目标方法,这就是返回的结果。目标方法是代表lambda主体的合成方法,或者是使用::运算符提供的任何命名方法。而实现该功能的接口的类
创建,则处理被推迟; 它不会在编译时发生。

最终,运行时invokedynamic使用引导程序结果1修补站点,该结果实际上是对传递的任何捕获值(包括(可能)调用目标2)的生成的委托的构造函数调用。通过消除后续调用的引导过程,这可以缓解性能下降的问题。

1由@Holger提供,请参见“链接的时序”一章的java.lang.invoke结尾。

2对于没有捕获的lambda,该invokedynamic指令通常将解析为共享委托实例,该实例可以在后续调用中重用,尽管这是实现细节。



 类似资料:
  • 我今天读了这篇关于lambdas的文章: http://www.infoq.com/articles/Java-8-Lambdas-A-Peek-Under-the-Hood 本文建议,lambda不是作为一个非内部类实现的(由于性能原因)。它给出了一个示例,可以将lambda表达式编译为类的(静态)方法。 我尝试了一个非常简单的片段: 输出是: 所以这不是同一个实例。它也不是一些中央的“Lamb

  • 问题内容: 在C#中,您可以将一个类标记为,以便只能从同一包中对其进行访问。Java有什么类似的东西吗? 问题答案: 您可以通过从类的声明中省略安全修饰符(公共,私有)来创建程序包专用类。

  • 问题内容: 我已经在这里阅读了很多帖子并在网上冲浪,但是也许我没有问正确的问题。我知道在集群可用之前,Redis目前是主/从服务器。但是,我想知道是否有人可以告诉我如何在逻辑上配置Redis以满足我的需要(或者如果它不是正确的工具)。 场景: 我们在美国的两端有2个站点。我们希望客户能够在每个站点上大量书写。然后,我们希望每个客户端也能够在其站点上执行读取。但是,我们希望在小于50ms的时间内从姐

  • 我在Windows Azure中开发了一个驻留在Windows Server 2012机器上的应用程序。应用程序充当许多并发网络连接的服务器,但流量非常低且稀少(客户机每隔几个小时才发送一次信息,但它们确实需要时刻连接,以便接收服务推送的更新)。 在没有流量的情况下几分钟后,客户机/服务器通信似乎被冻结,客户机和服务器之间没有流量流动。实际上,30-60秒后,客户端尝试发送一些东西,他们显示连接已

  • 问题内容: 在Java中,您可以使用匿名内部类内联定义一个新类。当您只需要重写类的单个方法时,这很有用。 假设您要创建一个仅覆盖单个方法的子类(例如)。在Java中,您可以编写如下代码: 这段代码创建了一个匿名类,该类仅扩展和覆盖方法。 Python中有类似的习语吗?在这些情况下使用哪种习语? 问题答案: 您可以使用内建函数即时创建类。例如: 由于OptionParser不是新式类,因此您必须显式

  • 问题内容: 我已经使用Tiles和Sitemesh多年了,虽然我个人更喜欢Sitemesh样式的页面装饰,但在Internet上我通常很少提及Sitemesh或Tiles。 人们是否在积极使用Tiles和/或Sitemesh,或者是否有其他图书馆以此身份接管? 问题答案: 我使用sitemesh,因为它比瓷砖的侵入性小。但是我认为tile通常与struct 1.x结合使用?