Java 8 requireNonNull метод с производительностью параметра поставщика

Метод Objects.requireNonNull с Supplier добавлен в Java 8, но я не уверен, что объявлено улучшение производительности:

Хотя это может дать преимущество в производительности в ненулевом случае, при принятии решения о вызове этого метода следует позаботиться о том, чтобы затраты на создание поставщика сообщений были меньше стоимости простого создания строкового сообщения напрямую.

Метод с String игнорирует параметр, если не ноль:

public static <T> T requireNonNull(T obj, String message) {
    if (obj == null)
        throw new NullPointerException(message);
    return obj;
}

Я нашел JDK-8011800: Добавить java.util.Objects.requireNonNull(T, Поставщик)

В JDK 7 java.util.Objects включал несколько методов для проверки на нулевое значение, в том числе один, который принимал сообщение для возврата, если нулевое было найдено. С лямбдами в JDK 8, другой вариант для включения - это метод requireNonNull, который принимает строку-поставщика вместо строки. Поэтому в ненулевом случае можно избежать затрат на создание строкового сообщения. Обратите внимание, что лямбда-захват может иметь ненулевую стоимость.

С комментариями указать отсутствие влияния на производительность:

Ненулевая стоимость захвата меня беспокоит. Я обеспокоен тем, что это часто стирает любые преимущества использования поставщика. 09-04-2013

Я нашел другие вопросы, но не ссылаясь на (почему) отправка параметра String имеют затраты производительности

Это специфично для лямбда-выражений / использования потока?

1 ответ

Решение

Учтите это, где generateString делает много вещей для генерации строки из someParam:

Objects.requireNonNull(obj, generateString(someParam));

Аргументы оцениваются с нетерпением в Java, что означает, что generateString будет оцениваться раньше requireNonNull называется. Поэтому он рассчитывается независимо от того, obj является нулевым или нет.

Вы можете решить эту проблему, изменив это на это:

Objects.requireNonNull(obj, () -> generateString(someParam));

В этом случае, generateString будет вызван только если obj на самом деле был нулевым. Это более эффективно, когда generateString дороже, чем создание Supplier-объект.

Вам следует просто использовать обычный не лямбда-метод, если ваш параметр String является просто литералом, например:

Objects.requireNonNull(obj, "obj was null!");
Другие вопросы по тегам