2

前言

本篇文章重点讨论JDK9中添加的静态方法,requireNonNullElserequireNonNullElseGet

正文

JDK9在Object类中新添加了两个静态方法,requreNonNullElse(T, T) requireNonNullElseGet(T obj,Supplier<? extends T> supplier)。这两个方法简化了判断对象是否为空(null),如果是空的则返回一个默认值。因此,这两个方法和早期JDK版本中引入的方法requireNonNull(T),requireNonNull(T,String)requireNonNull(T,Supplier<String>)可以用来进行防御性编程

在JDK9之前加入的三个方法并不支持在对象为空时返回一个默认值。取而代之的是,这三个方法会抛出NullPointerException。JDK9中新加入的两个方法则会在传入值为null时返回一个默认值。

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

在上面的例子中,如果提供的参数对象inputDate为null的话,默认值nownew Date()构造函数返回当前的时间)将会作为默认值返回。

JDK9还加了一个有相同功能的Objects.requireNonNullElseGet(T,Supplier<? extends T>)方法。这个方法和上一个方法的区别是,它接收一个Supplier对象来提供默认值,而不是直接返回一个同类型的对象作为默认值。

Modern Java Recipes, Ken Kousen 这本书中写道:Supplier S的基本用途之一就是支持延迟执行。在讨论了如何使用JDK中的Supplier之后,他还补充了:可以在代码中使用延迟执行,从而确保只有在时机合适时才会从Supplier处获取值。

下面展示了该方法的使用:

/**
 * 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时,该方法将不会被调用。

本文中提到的两个方法简化了判断一个参数是否为null并在为null时返回一个默认值的过程。它们最长用来实现防御性编程,当然也有其他的应用场景。


raledong
2.7k 声望2k 粉丝

心怀远方,负重前行