同时使用@Nonnull和Preconditions.checkNotNull(...)

时间:2016-10-19 12:04:38

标签: java null annotations guava

使用@Nonnull注释参数并稍后使用Preconditions.checkNotNull()检查相同是否有意义?

他们之间有什么区别?据我所知,使用@Nonnull只会指定一个合约,但除非您在IDE中说明,否则不会进一步检查。这是对的吗?

1 个答案:

答案 0 :(得分:5)

区别在于规范和实施之间。 @NonNull给出了例程的规范,Preconditions.checkNotNull()提供了一种验证例程的方法。

@NonNull指定一个形式参数的契约:永远不应该使用null作为相应的实际参数调用该方法。

有多种方法可以验证这样的规范。

  • 您可以使用assert语句或等效Preconditions.checkNotNull()执行运行时检查。这将在运行时动态查找违反合同的行为,并使程序崩溃。这可以通过提供更早的警告消息使您的代码更容易调试,但它不会提高代码质量。

  • 您可以使用IDE或其他工具在编译时执行静态检查。如果您使用声音工具,则可以保证不会有可能的执行违反规范并导致程序崩溃。

您需要说明您的方法,以记录它应该如何使用。您也可以使用@NonNull注释而不是英文作为Javadoc来编写,因为@NonNull简洁且机器可读。所以,你应该写@NonNull注释。

验证规范的正确性是可选的,但也很有用。使用运行时检查和静态检查进行验证是一种带式和吊带式方法。它使用两种不同的技术来验证规范。如果使用不健全的静态检查工具(如FindBugs),那么进行运行时检查是个好主意,因为即使FindBugs没有发出任何警告,代码中仍可能存在nullness错误。如果您使用声音工具,例如Nullness CheckerChecker Framework,那么运行时检查是无关紧要的。但是它们并没有太大的损害:只是一点点代码混乱和一点点运行时开销。

(请注意,如果将null值作为参数传递,则规范可能需要抛出特定异常。这将要求方法体包含Preconditions.checkNotNull()等代码,即使您有已经证明你的程序永远不会传递null。一个指示抛出的确切异常的规范对客户端代码并不特别有用。客户端实际上只想知道调用将在哪种情况下成功,并且客户端不太可能有{ {1}}专门阻止catch。因此,客户端在规范中需要的主要信息是null是非法值。)