@Nonnull和Objects.requireNonNull有什么区别

pri*_*ime 13 java

以下两个代码段之间有什么区别.

public Integer getId(@Nonnull SomeObject obj){  
    // do some stuff
    return id;
}

public Integer getId(SomeObject obj){   
    Objects.requireNonNull(SomeObject, "SomeObject is null");
    // do some stuff
    return id;
}
Run Code Online (Sandbox Code Playgroud)

它们之间有什么重大差异.在这些情况下进行空检查的正确方法是什么.

das*_*ght 17

这两者是互补的:@Nonnull注释记录了obj必须为非null 的事实,而Objects.requireNonNullcall确保obj在运行时非空.

你应该将两者结合起来,如下所示:

public Integer getId(@Nonnull SomeObject obj){   
    Objects.requireNonNull(SomeObject, "SomeObject is null");
    // do some stuff
    return id;
}
Run Code Online (Sandbox Code Playgroud)

相关文档@Nonnull可在此处找到:

可选的类型注释不能代替运行时验证

在Type Annotations之前,描述诸如nullability或range之类的内容的主要位置在javadoc中.使用Type注释,此通信以编译时验证的方式进入字节码.

您的代码仍应执行运行时验证.

  • @Alexander - 你会用Kotlin吗? (2认同)
  • 如果我错了,请纠正我,所以当我们使用 https://projectlombok.org/features/NonNull 时不需要 Objects.requireNonNull (2认同)

led*_*iov 6

区别在于,在第一种情况下,它是编译器和IDE的提示,参数不应为null,因此当您编写时,getId(null)您将收到错误.但有人可能会null在运行时传递价值.

至于第二种情况,它是一种防御性编程,当你以失败的速度进行时,前提是参数不应该是null.


Mak*_*oto 5

其中之一是实现JSR-305的注释,但更多的是用于静态分析而不是运行时保护。我记得,JSR-305 原则上是一个好主意,很多东西实际上都以某种方式利用它,但是当它的实用性只以静态分析的形式出现时,它就失去了很多意义。

举个例子:您的 IDE 可以利用它来警告您传递不应该传递的内容的情况,但它不能阻止您null在编译时传递到此方法。

Objects.requireNonNull是一个运行时强制执行,无论它传递的是什么,都将是一个非空引用。编译器也不能强制执行此操作,但是在运行时如果您收到一个空值,您将NullPointerException在执行该行代码时得到一个。

就正确性而言,使用Objects.requireNonNull是一个好主意,但这取决于您在运行应用程序时的义务。如果您必须在空值上失败,那么使用它很好,因为它会生成一个运行时异常来处理。如果你不能在一个空值失败,那么使用if支票,而不是效果会更好。