鉴于此:
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());
}
}
答案 0 :(得分:5)
这是Brett Oken关联的Brian Goetz's doc的摘录:
当编译器遇到lambda表达式时,它首先降低 (desugars)将lambda体转换为方法,其参数列表和 返回类型匹配lambda表达式的表达式,可能与某些表达式匹配 附加参数(对于从词法范围捕获的值,如果 任何。)在捕获lambda表达式的时刻, 它生成一个invokedynamic调用站点,在调用时返回 lambda所在的功能接口的一个实例 转换。这个调用站点被称为给定的lambda工厂 拉姆达。 lambda工厂的动态参数是值 从词汇范围中捕获。 lambda的bootstrap方法 factory是Java语言运行时库中的标准化方法, 称为lambda metafactory。静态引导参数捕获 关于lambda在编译时已知的信息(功能性的 它将被转换的接口,一个方法句柄 desugared lambda body,有关SAM类型的信息 可序列化等。)
方法引用的处理方式与lambda表达式相同, 除了大多数方法参考不需要被贬低为a 新方法;我们可以简单地加载一个常量方法句柄 引用的方法并将其传递给metafactory。
从同一文档中提取的示例:
举个例子,考虑一个捕获字段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; }
虽然
list.filter(String::isEmpty)
翻译为:
list.filter(indy(MH(metaFactory), MH(invokeVirtual Predicate.apply),
MH(invokeVirtual String.isEmpty))()))
答案 1 :(得分:1)
Here是方法引用的java语言规范。
Here是lambda表达式的规范。
从规则的角度来看,Lambdas相当复杂。
但是,在这两种情况下,结果都是一个invokedynamic调用。
Brian Goetz写了doc如何运作。
答案 2 :(得分:1)
在其中我们可以找到差异lambda表达式和方法引用的一种情况是将其用作Supplier接口的一部分。可以说我们有下面的静态方法
public static <T, E> T catchException(Supplier<T> resolver) {
try {
T result = resolver.get();
return result ;
} catch (Exception e) {
System.out.println("Exception");
return null;
}
}
当我们使用如下所示的lambda表达式调用该方法时,代码可以正常工作,因为lambda表达式作为Supplier的一部分传递并仅在捕获异常的get()方法被调用时执行。
List<String> underlyers=null;
System.out.println(catchException(()->underlyers.size()));
当我们使用如下所示的方法引用来调用方法时,在调用方法之前会得到NullPointerExecption,因为该引用是在传递给供应商之前执行的。在这种情况下,控件无法达到get()方法。
List<String> underlyers=null;
System.out.println(catchException(underlyers::size));