【问题标题】:How to use FindBugs’ @CheckForNull, @Nonnull and @Nullable annotations correctly如何正确使用 FindBugs 的 @CheckForNull、@Nonnull 和 @Nullable 注解
【发布时间】:2015-07-01 09:27:50
【问题描述】:

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

有两个包(annotations.jarjsr305.jar),每个包都有四个注释来实现这一点,以及根本不添加注释的选项。

【问题讨论】:

标签: java annotations signature findbugs


【解决方案1】:

这些是我经过一番尝试后的发现:

方法参数:

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

方法返回值:

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

使用哪个 JAR 文件:

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

【讨论】:

  • “错误标记出现”在 IDE 中,而不是在 Findbugs 中。 IDE 有自己的逻辑来处理@Nullable@CheckForNull。 Findbugs 是一个在命令行(或来自 Maven/gradle)上运行的工具,对于 findbugs,Nullable 的意思是“不要对被注释的事物产生任何警告”。
【解决方案2】:

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

如果您愿意尝试不同的静态分析工具,可以考虑Nullness CheckerChecker Framework

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

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

【讨论】:

    猜你喜欢
    • 2012-11-09
    • 1970-01-01
    • 2012-08-31
    • 1970-01-01
    • 1970-01-01
    • 2015-12-15
    • 2015-03-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多