鉴于这种:
class MyClass {
static class A {
public boolean property() {
return Math.random() < 0.5;
}
}
static List<A> filterLambda(List<A> list) {
return list.stream().filter(a -> a.property()).collect(Collectors.toList());
}
static List<A> filterMethodCall(List<A> list) {
return list.stream().filter(A::property).collect(Collectors.toList());
}
}
- 有什么区别编译器做什么对于每种方法?
- 如果有的话,内存使用或运行时间是否有差异? (即使很小,这个问题也只是学术性的)
PD:我知道这个问题类似于this one但我认为这个问题没有得到正确解决。
这是摘录自布莱恩·戈茨的医生由布雷特·奥肯链接:
当编译器遇到 lambda 表达式时,它首先降低
(脱糖)将 lambda 主体放入方法中其参数列表和
返回类型与 lambda 表达式匹配,可能与某些
附加参数(对于从词法范围捕获的值,如果
任何。)在 lambda 表达式被捕获的点,
它生成一个 invokedynamic 调用站点,该调用站点在被调用时返回
lambda 所针对的功能接口的实例
转换。该调用站点称为给定的 lambda 工厂
拉姆达。 lambda 工厂的动态参数是值
从词法范围捕获。 lambda 的 bootstrap 方法
工厂是Java语言运行时库中的标准化方法,
称为 lambda 元工厂。静态引导参数捕获
编译时有关 lambda 的已知信息(函数
它将被转换到的接口,方法句柄
脱糖 lambda 主体,有关 SAM 类型是否为的信息
可序列化等)
方法引用的处理方式与 lambda 表达式相同,
除了大多数方法引用不需要脱糖到
新方法;我们可以简单地加载一个常量方法句柄
引用的方法并将其传递给元工厂。
从同一文档中提取的示例:
作为示例,考虑一个捕获字段 minSize 的 lambda:
list.filter(e -> e.getSize() < minSize )
我们将其脱糖为实例方法,并将接收者作为第一个捕获的参数传递:
list.forEach(INDY((MH(metaFactory), MH(invokeVirtual Predicate.apply),
MH(invokeVirtual B.lambda$1))( this ))));
private boolean lambda$1(Element e) {
return e.getSize() < minSize; }
While
list.filter(String::isEmpty)
翻译为:
list.filter(indy(MH(metaFactory), MH(invokeVirtual Predicate.apply),
MH(invokeVirtual String.isEmpty))()))
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)