Есть ли разница между 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, так что это мало что доказывает.

Ответы на вопрос(1)

Ваш ответ на вопрос