为什么要使用 Objects.requireNonNull()?快速故障

2022-08-31 04:47:46

我注意到Oracle JDK中的许多Java 8方法都使用,如果给定的对象(参数)是,则在内部抛出。Objects.requireNonNull()NullPointerExceptionnull

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

但是,如果对象被取消引用,则无论如何都会被抛出。那么,为什么要做这个额外的空检查并抛出呢?NullPointerExceptionnullNullPointerException

一个明显的答案(或好处)是它使代码更具可读性,我同意。我很想知道在方法开始时使用的任何其他原因。Objects.requireNonNull()


答案 1

因为你可以通过这样做来明确事情。喜欢:

public class Foo {
  private final Bar bar;

  public Foo(Bar bar) {
    Objects.requireNonNull(bar, "bar must not be null");
    this.bar = bar;
  }

或更短:

  this.bar = Objects.requireNonNull(bar, "bar must not be null");

现在您知道了

  • Foo 对象是使用new()
  • 条形图字段保证为非空值。

与此相比:您今天创建了一个 Foo 对象,明天您调用了一个使用该字段并抛出的方法。最有可能的是,您明天不会知道为什么该引用昨天在传递给构造函数时为空!

换句话说:通过显式使用此方法检查传入的引用,您可以控制将引发异常的时间点。大多数时候,你想尽快失败

主要优点是:

  • 如前所述,受控行为
  • 更容易调试 - 因为你在对象创建的上下文中抛出。在某个时间点,您有一定的机会,您的日志/跟踪会告诉您出了什么问题!
  • 如上所示:这个想法的真正力量与最终领域一起展开。因为现在你的类中的任何其他代码都可以安全地假设它不是空的 - 因此你不需要在其他地方进行任何检查!barif (bar == null)

答案 2

快速故障

代码应尽快崩溃。它不应该做一半的工作,取消引用null,然后崩溃,留下一半完成的一些工作,导致系统处于无效状态。

这通常称为“提前失败”或“快速失败”。


推荐