Consider the following class:
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;
}
}
The first predicate is created from a method reference and the other a lambda expression. These predicates have the same behavior (nonNull
's body is just return obj != null;
). The lambda is two characters shorter (perhaps allowing a stream pipeline to fit on one line).
Other than code style, is there any difference between Objects::nonNull
and x -> x != null
? Put another way, should I prefer one over the other?
The lambda-dev and lambda-libs-spec-{observers,experts} mailing list messages mentioning isNull
, nonNull
and isNotNull
(early name) didn't address this point. (I'm surprised no one questioned adding the Objects methods as they are trivially replaceable with a lambda, but on the other hand, so is Integer::sum
.)
I also looked at the bytecode with javap
. The only difference was the method handle passed to the 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
Of course, the metafactory could do different things for method references and lambdas, at the whim of the JVM, so that doesn't prove much.
See Question&Answers more detail:os