Objects::nonNull 和 x -> x != null 之间有什么区别吗?
请考虑以下类:
import java.util.Objects;
import java.util.function.Predicate;
public class LambdaVsMethodRef {
public static void main(String[] args) {
Predicate<Object> a = Objects::nonNull;
Predicate<Object> b = x -> x != null;
}
}
第一个谓词是从方法引用创建的,另一个谓词是从 lambda 表达式创建的。这些谓词具有相同的行为(的主体只是 )。lambda 缩短了两个字符(可能允许流管道适合一行)。nonNull
return obj != null;
除了代码样式之外,Objects::nonNull
和 x -> x != null
之间有什么区别吗?换句话说,我应该更喜欢一个而不是另一个吗?
lambda-dev 和 lambda-libs-spec-{observers,experts} 邮件列表消息提到 和 (早期名称) 没有解决这一点。(我很惊讶没有人质疑添加Objects方法,因为它们可以很容易地用lambda替换,但另一方面,也是如此。isNull
nonNull
isNotNull
Integer::sum
我还用.唯一的区别是传递给 lambda 元工厂引导方法的方法句柄:javap
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
当然,元工厂可以根据JVM的心血来潮为方法引用和lambda做不同的事情,所以这并不能证明什么。