考虑以下课程:
import java.util.Objects;
import java.util.function.Predicate;
public class LambdaVsMethodRef {
public static void main(String[] args) {
Predicate a = Objects::nonNull;
Predicate b = x -> x != null;
}
}
第一个谓词是从方法引用创建的,另一个是lambda表达式.这些谓词具有相同的行为(nonNull的主体只是返回obj!= null;). lambda短两个字符(可能允许流管道适合一行).
除了代码风格,Objects :: nonNull和x – >之间有什么区别吗? x!= null?换句话说,我应该更喜欢一个吗?
lambda-dev和lambda-libs-spec- {观察者,专家}邮件列表消息提到isNull,nonNull和isNotNull(早期名称)没有解决这一点. (我很惊讶没有人质疑添加Objects方法,因为它们可以用lambda轻松替换,但另一方面,Integer :: sum也是如此.)
我还用javap查看了字节码.唯一的区别是传递给lambda metafactory bootstrap method的方法句柄:
BootstrapMethods:
0: #16 invokestatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
Method arguments:
#17 (Ljava/lang/Object;)Z
#18 invokestatic java/util/Objects.nonNull:(Ljava/lang/Object;)Z
#17 (Ljava/lang/Object;)Z
1: #16 invokestatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
Method arguments:
#17 (Ljava/lang/Object;)Z
#20 invokestatic LambdaVsMethodRef.lambda$main$1:(Ljava/lang/Object;)Z
#17 (Ljava/lang/Object;)Z
当然,对于方法引用和lambdas来说,元数据可以在JVM的奇思妙想中做不同的事情,所以这并不是很有效.