15

我在方法参数上使用 Findbugs 和 javax.annotation.Nonnull。

在私有方法上,我通常添加一个断言行来检查空值,例如

private void myMethod(@Nonnull String str) {
    assert str != null
    ....

最新的 Netbeans 版本 (7.3rc2) 报告断言检查是不必要的(因为 Nonnull 注释)。我不完全确定这是否是 Netbeans 错误。

可以因为我指定了 @Nonnull 注释而删除断言行吗?

据我了解,注释仅在静态分析期间使用,而断言在启用时在执行期间处于活动状态,因此两者不可替代。

4

4 回答 4

13

断言在运行时被评估,注解帮助 FindBugs 在运行前的分析过程中发现问题。由于这两项检查并不真正冲突,您可以同时保留它们。如果我的 IDE 告诉我删除断言,我会觉得很烦人。

于 2013-02-14T12:25:59.050 回答
8

Netbeans 是对的。如果您认为它可以为空:删除注释。如果您知道它不能:删除断言。

如果您的方法有可能被调用为空值,那么@Nonnull注释不应该存在。

就像您说的那样,该注释实际上在运行时并没有做任何事情:它仅由 IDE 和静态代码分析工具使用。它不能确保事物不为空。

于 2013-02-11T10:31:55.037 回答
1

由于这是私有方法,我们可以确保带注释的参数不能为空。我认为您可以删除此断言。

如果 NetBeans 警告公共方法,我认为它有问题。我建议你提出断言。

如果您仍然觉得私有方法中的断言是必要的,我认为您可以使用字节码注入。例如,这是一个注入空检查的 Maven 插件。抱歉,这是我的个人项目,但它对我有用。我想它可以满足你的需要。 https://github.com/KengoTODA/jsr305-maven-plugin

于 2013-02-12T00:06:30.913 回答
0

当我在考虑我的 IDE 警告时,我找到了一个不同的解决方案。

最初,我觉得 IDE 是错误的。我是一个偏执的程序员,并且希望拥有用于文档和静态分析的标签以及运行时检查,以防我从反射或其他 JVM 语言或其他不可静态分析的东西中使用它,所以我认为这是错误的给我一个警告并告诉我assert(x != null)不需要声明。

-ea但是后来我想到了如何根据在运行时传递给 Java的标志的状态来删除断言,assert并且在某些方面@Nonnull实际上都是仅用于开发的检查。

事实证明,可以插入一个实际的运行时检查(Java 7+)Objects.requireNonNull,它会抛出一个NullPointerException并且不能用-ea断言删除。我想我会更喜欢这个而不是我的assert(x != null); use(x);模式。

public ConstructorForClass(@Nonnull Type x) {
  this.x = Objects.requireNonNull(x);
  //...
}
于 2015-06-04T14:17:15.543 回答