Existe alguma diferença entre Objects :: nonNull ex -> x! = Null?
Considere a seguinte classe:
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;
}
}
O primeiro predicado é criado a partir de uma referência de método e o outro uma expressão lambda. Esses predicados têm o mesmo comportamento (nonNull
o corpo é apenasreturn obj != null;
) O lambda é dois caracteres mais curto (talvez permitindo que um pipeline de fluxo caiba em uma linha).
Além do estilo do código,existe alguma diferença entreObjects::nonNull
ex -> x != null
? Em outras palavras, devo preferir um ao outro?
As mensagens da lista de mensagens lambda-dev e lambda-libs-spec- {observators, experts} mencionandoisNull
, nonNull
eisNotNull
(nome antigo) não abordou esse ponto. (Estou surpreso que ninguém questionou a adição dos métodos Objects, pois eles são trivialmente substituíveis por um lambda, mas, por outro lado, também éInteger::sum
.)
Eu também olhei para o bytecode comjavap
. A única diferença era o identificador do método passado para ométodo de inicialização metafactory lambda:
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
Obviamente, a metafábrica poderia fazer coisas diferentes para referências de método e lambdas, ao capricho da JVM, para que isso não provasse muito.