Статьи

JDK 9: в класс объектов добавлены методы NotNullOrElse

JDK 9 добавил несколько новых методов в класс Objects, включая два static метода, выделенных в этом посте: requireNonNullElse (T, T) и requireNonNullElseGet (T obj, Supplier <? Extends T> supplier) . Оба метода облегчают проверку того, что данный объект не является null и предоставляют альтернативу, если предоставленная переменная оказывается null . Таким образом, эти методы и аналогичные методы, представленные в Objects в более ранних версиях JDK [ requireNonNull (T) , requireNonNull (T, String) и requireNonNull (T, Supplier <String>) ], наиболее вероятно, будут использоваться для реализовать пункты охраны в методах.

Три метода, упомянутых в последнем абзаце, которые были добавлены к Objects до JDK 9, не позволяли использовать значение «по умолчанию», когда тестируемый объект был определен как null . Вместо этого каждый из этих трех методов генерирует исключение NullPointerException, когда переданная им переменная имеет значение null . Два метода, добавленные в Objects в JDK 9, позволяют указывать значение по умолчанию, которое может быть возвращено методом, а не методом, NullPointerException исключение NullPointerException .

Objects.requireNonNullElse (T, T) — это самый простой подход из двух новых добавленных методов для указания объекта по умолчанию, который будет возвращен, когда проверяемая переменная имеет значение null . Пример применения этого метода показан в следующем листинге кода.

Пример Objects.requireNonNullElse​(T,T)

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
/**
 * Provide instance of {@code Instant} that corresponds to
 * the provided instance of {@code Date}.
 *
 * @param inputDate Instance of {@code Date} for which
 *    corresponding instance of {@code Instant} is desired;
 *    if this is {@code null}, an {@code Instant} representing
 *    "now" will be returned.
 * @return Instance of {@code Instant} extracted from provided
 *    {@Date} that will instead represent "now" if provided
 *    {@code Date} is {@code null}.
 */
public Instant convertDateToInstantWithNowDefault(final Date inputDate)
{
   final Date dateToConvert
      = Objects.requireNonNullElse(inputDate, new Date());
   return dateToConvert.toInstant();
}

В приведенном выше примере, если предоставленная переменная типа Date имеет значение null , вместо нее возвращается предоставленное значение по умолчанию «now» (основанное на вызове конструктора Date, который не принимает аргументы ).

JDK 9 также добавил метод Objects.requireNonNullElseGet (T, Supplier <? Extends T>) для аналогичной цели. Этот метод отличается от ранее обсуждавшегося метода тем, что он принимает поставщика для предоставления значения по умолчанию, а не принимает другой объект того же типа в качестве значения по умолчанию.

В книге « Современные рецепты Java» , которую настоятельно рекомендует, Кен Коузен пишет: «Один из основных вариантов использования Supplier — поддержка концепции отложенного выполнения ». После обсуждения того, как Supplier используется в JDK, он добавляет: «Этот процесс отложенного выполнения может использоваться в вашем собственном коде, чтобы гарантировать, что значение извлекается из Supplier только при необходимости». Мой следующий пример демонстрирует это.

Далее приведен список тщательно продуманного кода, который демонстрирует использование этого метода для принятия Supplier .

Пример Objects.requireNonNullElseGet​(T,Supplier<? extends T>)

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
/**
 * Provide instance of {@code Instant} that corresponds to
 * the provided instance of {@code Date}.
 *
 * @param inputDate Instance of {@code Date} for which
 *    corresponding instance of {@code Instant} is desired;
 *    if this is {@code null}, an {@code Instant} based on
 *    a complicated date calculation will be returned.
 * @return Instance of {@code Instant} extracted from provided
 *    {@Date} that will instead represent a calculated date if
 *    provided {@code Date} is {@code null}.
 */
public Instant convertDateToInstantWithCalculatedDefault(final Date inputDate)
{
   final Date dateToConvert
      = Objects.requireNonNullElseGet(inputDate, () -> calculateDate());
   return dateToConvert.toInstant();
}

Версия метода, принимающего Supplier может быть выгодной, когда ожидается, что код для определения значения по умолчанию будет долгосрочным. В таких случаях этот длительный метод выполняется только в том случае, если первый переданный аргумент равен null . Когда первый переданный аргумент не равен null , длительный метод не вызывается. [Между прочим, я здесь не показываю реализацию метода calculateDate() потому что она смехотворно надумана, но достаточно сказать, что ее намеренное выполнение занимает очень много времени.]

Два метода, описанные в этом посте, позволяют легко определить, является ли конкретная переменная null и обеспечить подходящую замену вместо нее, если она null . Скорее всего, они чаще всего используются для реализации «защитных предложений», но их способность возвращать значение по умолчанию может также привести к дополнительным случаям использования.

Опубликовано на Java Code Geeks с разрешения Дастина Маркса, партнера нашей программы JCG . См. Оригинальную статью здесь: JDK 9: Методы NotNullOrElse, добавленные в класс объектов

Мнения, высказанные участниками Java Code Geeks, являются их собственными.