Есть ли разница между 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;
}
}
Первый предикат создается из ссылки на метод, а другой - лямбда-выражения. Эти предикаты имеют одинаковое поведение (nonNull
тело простоreturn obj != null;
). Лямбда короче на два символа (возможно, позволяя потоковому конвейеру помещаться на одной строке).
Кроме стиля кода,есть ли разница междуObjects::nonNull
а такжеx -> x != null
? Другими словами, я должен предпочесть одно другому?
Сообщения в списках рассылки lambda-dev и lambda-libs-spec- {наблюдатели, эксперты}isNull
, nonNull
а такжеisNotNull
(раннее имя) не обращался к этому вопросу. (Я удивлен, что никто не сомневался в добавлении методов Objects, поскольку они тривиально заменяемы лямбда-выражениями, но с другой стороны,Integer::sum
.)
Я также посмотрел на байт-код с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, так что это мало что доказывает.