![Java 8 lambda是否被编译为内部类,方法或其他东西?[重复],第1张 Java 8 lambda是否被编译为内部类,方法或其他东西?[重复],第1张](/aiimages/Java+8+lambda%E6%98%AF%E5%90%A6%E8%A2%AB%E7%BC%96%E8%AF%91%E4%B8%BA%E5%86%85%E9%83%A8%E7%B1%BB%EF%BC%8C%E6%96%B9%E6%B3%95%E6%88%96%E5%85%B6%E4%BB%96%E4%B8%9C%E8%A5%BF%EF%BC%9F%5B%E9%87%8D%E5%A4%8D%5D.png)
假设您传递的是 实际的lambda表达式
而不是方法引用,则表达式本身将被编译为单独的合成方法。除了预期功能接口的任何形式参数(例如,
String在情况下为单个
Consumer<String>),它还将包含任何捕获值的参数。
在出现lambda表达式或方法引用的代码位置,将
invokedynamic发出一条指令。第一次点击此指令时,会在上调用一个引导方法
Lambdametafactory。该引导方法将修复目标功能接口的实际实现,该目标函数接口委托给目标方法,这就是返回的结果。目标方法是代表lambda主体的合成方法,或者是使用
::运算符提供的任何命名方法。而实现该功能的接口的类
被 创建,则处理被推迟; 它不会在编译时发生。
最终,运行时
invokedynamic使用引导程序结果1修补站点,该结果实际上是对传递的任何捕获值(包括(可能)调用目标2)的生成的委托的构造函数调用。通过消除后续调用的引导过程,这可以缓解性能下降的问题。
1由@Holger提供,请参见“链接的时序”一章的java.lang.invoke结尾。
2对于没有捕获的lambda,该
invokedynamic指令通常将解析为共享委托实例,该实例可以在后续调用中重用,尽管这是实现细节。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)