Java @Nonnull和Objects.requirennull之间有什么区别

Java @Nonnull和Objects.requirennull之间有什么区别,java,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; } 它们之间的

以下两段代码之间的区别是什么

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

它们之间的显著区别是什么。在这些情况下,执行空检查的正确方法是什么

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


至于第二种情况,这是一种防御性编程,当您在参数不应为
null

的前提下快速失败时,两者是互补的:
@Nonnull
注释记录了
obj
必须为非null的事实,而
Objects.requirennoull
调用确保
obj
在运行时不为null

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

public Integer getId(@Nonnull SomeObject obj){   
    Objects.requireNonNull(SomeObject, "SomeObject is null");
    // do some stuff
    return id;
}
有关
@Nonnull
的相关文档可以找到:

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

在类型注释之前,用于描述空性或范围等内容的主要位置在javadoc中。对于类型注释,这种通信以编译时验证的方式进入字节码

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


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

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

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


就正确性而言,使用
Objects.requirennull
是一个好主意,但这取决于运行应用程序时您的义务。如果您必须在空值上失败,那么使用它就可以了,因为它将生成一个要处理的运行时异常。如果不能在空值上失败,然后改用
if
检查会更好。

多个方面中的一个:与Objects.requireNoll相反,如果不考虑注释,则注释不一定做任何事情。
@Nonnull
告诉编译器给定的参数不应为
null
,然而,
requirennoull
检查给定对象是否为
null
。上帝啊,对于一个正确的不可为null的引用类型,我会怎么做(你以后可以使用它引用一个选项/可选/可能类型)@Alexander-你会使用Kotlin吗?我注意到javax.annotation中的非null接口具有
@保留(RetentionPolicy.RUNTIME)
。有人知道这是什么意思吗?如果我错了,请纠正我,这样当我们使用@DasbLinkedOnlight时就不需要Objects.requireNonNull了是的,在这种情况下,我认为库将负责运行时验证。@prime yes,在运行时,当null值作为参数传递,并且您调用该对象的方法时。