Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

JDK 9: NotNullOrElse Methods Added to Objects Class

DZone's Guide to

JDK 9: NotNullOrElse Methods Added to Objects Class

Let's take some of the new Objects class methods introduced in Java 9 for a spin. Here we'll focus on the static methods requireNonNullElse and requireNonNullElseGet.

· Java Zone ·
Free Resource

Download Microservices for Java Developers: A hands-on introduction to frameworks and containers. Brought to you in partnership with Red Hat.

JDK 9 added some new methods to the Objects class including two static methods highlighted in this post: requireNonNullElse(T,T) and requireNonNullElseGet(T obj,Supplier<? extends T> supplier). Both methods make it easier to verify that a given object is notnull and to provide an alternative if the provided variable turns out to be null. As such, these methods and the similar methods introduced to Objects in earlier JDK versions [requireNonNull(T), requireNonNull(T,String), and requireNonNull(T,Supplier<String>)] are most likely to be used to implement guard clauses in methods.

The three methods mentioned in the last paragraph that were added to Objects prior to JDK 9 did not allow a "default" value to be used when the object being tested was determined to be null. Instead, each of these three methods throws a NullPointerException when the variable passed to them is null. The two methods added to Objects in JDK 9 do allow a default to be specified that can be returned by the method rather than the method throwing a NullPointerException.

Objects.requireNonNullElse(T,T) is the most straightforward approach of the two new added methods for specifying a default object to be returned when the provided variable under test is null. An example of applying this method is shown in the next code listing.

Example of Objects.requireNonNullElse(T,T)

/**
 * 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();
}


In the above example, if the provided variable of type Date is null, a provided default of "now" (based on calling the Date constructor that doesn't accept arguments) is returned instead.

JDK 9 also added the method Objects.requireNonNullElseGet(T,Supplier<? extends T>) for a similar purpose. This method differs from the previously discussed method in that it accepts a Supplier for providing the default value rather than accepting another object of the same type to serve as the default.

In the highly recommended book Modern Java Recipes, Ken Kousen writes, "One of the primary use cases for Suppliers is to support the concept of deferred execution." After discussing how Supplier is used in the JDK, he adds, "This process of deferred execution can be used in your own code, to ensure that a value is retrieved from the Supplier only when appropriate." My next example demonstrates this.

A highly contrived code listing is shown next and demonstrates the use of this method accepting a Supplier.

Example of Objects.requireNonNullElseGet(T,Supplier<? extends T>)

/**
 * 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();
}


The version of the method accepting a Supplier may be advantageous when the code for determining the default is expected to be long-running. In such cases, that long-running method is only executed if the first passed-in argument is null. When the first passed-in argument is notnull, the long-running method is not invoked. [By the way, I don't show the implementation of calculateDate() here because it's ridiculously contrived, but suffice it to say that it intentionally takes a very long time to execute.]

The two methods covered in this post make it easy to detect if a particular variable is null and to provide a suitable replacement in its stead when it is null. These are likely to be most often used to implement "guard clauses," but their ability to return a default value could lead to additional use cases as well.

Download Building Reactive Microservices in Java: Asynchronous and Event-Based Application Design. Brought to you in partnership with Red Hat

Topics:
java ,java 9 ,null ,objects class ,tutorial

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}