提到Java没有人不想到大名鼎鼎的NPE(Null Pointer Error),可见广大程序员受其毒害之深。所以做接口设计的时候,一个好的习惯就是注明Nullbility。 对于Nullable的参数或者返回值,从Java 8后Optional 是推荐的方式,因为它强迫接口使用者显示进行空值检测。 但如果接口设计中是想注明非空的情况呢,通常情况下你会发现有两个看起来很类似的annotation, @NotNull 以及 @Nonnull, 而且你可能会发现代码库里使用两者的都有。但是,正如Stackoverflow上的这个帖子分析道:
// 用于Java Bean运行时校验,并不用于静态分析
javax.validation.constraints.NotNull
// 被Findbugs用于代码静态分析,已被Deprecate来推荐JSR-305
edu.umd.cs.findbugs.annotations.NonNull
// JSR-305标准,被Findbugs支持并推荐
javax.annotation.Nonnull
// 被Intelliji用来做静态分析
org.jetbrains.annotations.NotNull
准确地说,你应该在接口设计时使用@Nonnull,而且为了达到预计效果,你必须要使用支持JSR-305标准的静态分析工具,比如Findbugs,IDEA或者Checker Framework,不然其效果就是个注释作用,并没有实际检查约束效果。如果你使用了Findbugs而且设置了所有Findbugs错误都会让你的build fail,这样你才充分利用了这个annotation。
那么NotNull该什么使用呢?这个annotation是用在运行时数值验证的,比如:
import javax.validation.constraints.NotNull; public class Person { @Id private String id; private String username; private String password; @NotNull private String email; }
你注明了email不能为空,当你从数据库中加载数据到这个model后你就可以调用validator来检验创建的对象是否遵守规范,或者Person这个对象是Spring web resource的一个请求参数,比如:
public Response register(@Valid Person person) {...}
如果你的web应用开启了bean validation的话person参数就会被自动校验,如果email为null的话resource就会自动返回400 BAD_REQUEST响应,因为客户端发送了一个不合格的数据。
所以看似相似确大不相同,需谨慎使用。