4

我应该使用哪个@NotNull Java 注释?已经过时并且有点基于意见。从那时起,Java 8 和更新的 IDE 一起出现了。

虽然 Java 8 允许通过集成JSR 308来进行类型注释,但它没有附带任何注释。来自JSR 308 解释:Josh Juneau 的 Java 类型注释

JSR 308,Java 类型的注释,已作为 Java SE 8 的一部分被合并
。...
编译器检查器可以被编写来验证带注释的代码,当代码不满足某些要求时,通过生成编译器警告来强制执行规则。Java SE 8 不提供默认的类型检查框架,但可以编写自定义注解和处理器来进行类型检查。还有许多类型检查框架可以下载,它们可以作为 Java 编译器的插件来检查和强制执行已注释的类型。类型检查框架包括类型注释定义和一个或多个与编译器一起用于注释处理的可插入模块。

仅考虑提供至少某种@CanBeNulland的解决方案@CannotBeNull,我发现了以下信息(可能是错误的):

有些用于静态代码分析,有些用于运行时验证。

上述选项之间的实际区别是什么?是否有(将会有)一个标准,还是每个人都可以编写自己的分析框架?

4

2 回答 2

5

除了您提到的之外,还存在其他一些无效性分析;例如,IntelliJ 包含nullness analysis

以下是关于空值分析的一些关键问题:

  • 它是在编译时工作还是在运行时工作?编译时分析给程序员提前警告潜在的错误。通过运行时分析,您的程序仍然会崩溃,但它可能会更早地崩溃或带有更多信息的错误消息。

  • 它是验证者还是错误发现者?验证者提供正确性保证:如果工具没有报告任何潜在错误,则程序在运行时不会遇到给定的错误。错误查找器报告了一些问题,但如果它没有报告任何问题,那么您的程序可能仍然是错误的。验证者通常需要程序员做更多的工作,包括对程序进行注释。开始使用错误查找器可能需要较少的努力,因为它可以在未注释的程序上运行(尽管在这种情况下它可能不会给出很好的结果)。

  • 分析的精确度如何?当程序实际正确时,它多久遭受一次错误警报或发出警告?它多久会错过警报,或者没有通知您程序中的真正错误?

  • 工具是否内置在 IDE 中?如果是这样,它可能更容易使用。如果没有,任何程序员都可以使用它,而不仅仅是使用该特定 IDE 的程序员。

您提到的三个工具都在编译时工作。FindBugs 是一个 bug 查找器,其他的是验证器。Checker Framework 具有更好的精度,但其他两个具有更好的 IDE 集成。FindBugs 不适用于 Java 8 类型注释 (JSR 308);其他两个都支持 Java 8 和 pre-Java-8 注释。所有这些工具都在程序员的工具箱中占有一席之地。哪一个适合您取决于您​​的需求和目标。

要回答您的其他一些问题:

FindBugs 的注释使用javax域是因为它的设计者希望 Oracle 将 FindBugs 用作 Java 标准(!)。从未发生过。你是对的,使用javax混淆了许多人认为它是官方的或受 Oracle 青睐的,但事实并非如此。

是否有(将会有)一个标准,还是每个人都可以编写自己的分析框架?

目前,甲骨文希望社区尝试创建和使用各种分析框架。他们觉得他们还没有充分了解各种方法的优缺点来创建一个标准。他们不想过早地创建一个包含有缺陷的方法的标准。他们愿意在未来创建标准。

于 2016-08-26T12:44:30.387 回答
5

您收集的信息几乎已经描述了它:

基于类型注释 (JSR 308) 的静态分析确实比以前的方法强大得多。

两组注释使用 JSR 308,都是为了执行静态分析(也可以认为是高级类型检查)。促进这些注释的两个工具的核心本质上是兼容的(并且每个工具也可以使用另一个的注释)。我知道的差异主要在两个方面:

  • IDE 集成。
  • 未注释类型的解释。在严格的世界中,每种类型都是非空或可为空的,因此如果缺少注释,则默认情况下可以将其解释为非空。或者,底层类型系统可以使用“遗留类型”的概念,在需要“未经检查的转换”时发出警告(类似于泛型类型和原始类型的组合)。据我所知,Checkers Framework 应用了严格的方法,而 Eclipse 允许您在@NonNullByDefault策略和承认“遗留类型”(为了迁移)之间进行选择。

同样据我所知,目前没有人计划投资于这些注释的标准化。

于 2016-08-26T12:16:23.837 回答