如何正确使用FindBugs的@CheckForNull,@ Nonull和@Nullable注释

时间:2015-07-01 09:27:50

标签: java annotations signature findbugs

我想正式注释我的函数签名以澄清他们的合同 - 特别是如果允许或禁止null参数和返回值 - 以FindBugs的静态代码分析工具(可能还有其他)可以使使用它。

有两个包(annotations.jarjsr305.jar),每个包含四个注释,以及根本不添加注释的选项。

2 个答案:

答案 0 :(得分:9)

这些是我经过一些尝试后的调查结果:

方法参数:

  • 参数不能为null:不要添加任何注释。在这种情况下,如果null传递给方法,则会出现错误标记。 (我在设置@Nonnull注释时曾经预料到这种行为,但是当我提出它时,根本没有出现错误标记。)
  • 参数可以是null:添加@Nullable注释。@CheckForNull的效果相同。@Nullable documentation读取: “FindBugs会将带注释的项目视为没有注释。”事实并非如此。如果我致电string.length()String string已标记为@Nullable,则会导致出现错误标记,如果没有注释,则没有错误标记显示。)

方法返回值:

  • 方法永不返回null:置@Nonnull如果您尝试从方法内部return null;,则会导致错误标记。
  • 方法可以返回null:您是否要对其执行检查?如果返回值确实取决于只能在调用时知道的方法参数,则检查可能是开销,例如“如果参数1为负,则我的方法返回null”。在这种情况下我不会给出注释。但是,您可能需要考虑抛出IllegalArgumentException而不是返回null
  • 方法可以返回null并且应始终检查返回对象:放@CheckForNull但是,在许多情况下还有更好的方法,你可能想要考虑返回Collections.emptyList()代替null列表,或者抛出MissingResourceExceptionIOException或其他适当的例外。

使用哪个JAR文件:

  • 两个jar文件都会导致FindBugs的相同行为,唯一的区别是来自annotations.jar的注释在Eclipse中显示为已弃用。因此,请使用jsr305.jar
  • 需要jar文件。使用给定的包和类名创建空注释不起作用。你可以get it here

答案 1 :(得分:4)

@Paramaeleon提供了一些很好的提示,例如你必须如何保留一个未注释的方法参数,因为如果你写@Nonnull,FindBugs会毫不直观地抑制所有警告。

如果您愿意尝试使用其他静态分析工具,可以考虑Nullness CheckerChecker Framework

主要区别在于Nullness Checker旨在检测所有空指针错误。相比之下,FindBugs故意不会向您报告一些可能的错误,以便报告较少的误报警告。两种工具都可以为您编写的注释提供更好的结果。如果您不愿意编写任何注释,那么FindBugs是一个更合适的工具。如果您愿意编写注释,那么Checker Framework可能会更好。

Nullness Checker手册在其关于choosing a nullness analysis tool的部分中包含更多比较。