概述
自从spring5开始,我们现在可以利用一个有趣的功能来有帮助我们编写更加安全的代码。这个功能被称为空安全(null-safety),一组注解像监控设施一样工作,监控潜在的空引用。
null-safety功能在编译其间生成警告,从而不让不安全的代码从我们手中逃脱。这样的警告可以在运行时避免产生灾难性的空指针异常(NPEs——null pointer exceptions)。
1. @NonNull
@NonNullAnnotation是null-safety功能所有注解中最重要的注解。我们能够使用这个注解在任何需要对象引用的地方声明非空限约束:一个字段、一个方法的参数或者一个方法的返回值。
public class Person { private String fullName; void setFullName(String fullName){ if(fullName != null && fullName.isEmpty()){ fullName = null; } this.fullName = fullName; } }
上面代码是合理的,但是存在一个缺陷——这个fullName字段可能被设置为null,如果这件事情发生,我们在使用fullName的时候会由于产生NPE(null-pointer-exception)而终止程序。
Spring的null-safety功能可以使工具报告这一个危险警告。
注意:null-safety功能只会使用工具或在编译期间发出这样的警告,而不会影响程序的正常运行,比如我们将上面的示例中的fullName加上@NonNull的注解,只会在Idea(本人使用的工具是idea)中产生一条编译相关警告。

在Idea中的体现图示如下:

得益于这个标识,我们可以提前意识到问题,并且能够采取行动回避这个运行时异常。
2. @NonNullFields
@NonNull注解在保证空的安全性上是有帮助的。然而,如果我们用这个注解修饰所有的非空字段就会污染整个代码库。
我们使用@NonNullFields注解可以避免滥用@NonNull。这个注解适用于包级别,通知我们的开发工具,这个被注解的包下面的所有字段,默认,都是非空的。
由于@NonNullFields注解开始生效,我们需要在这个包的根目录创建一个名为package-info.java的文件,并且使用@NonNullFields来注解这个包。项目结构及pakcage-info.java的代码图示如下:

3. @Nullable
@NonNullFields注解在帮助我们减少样板代码方面比@NonNull更有优势(如果一个包中有很多字段都需要非空标识,需要大量的使用@NonNull注解而导致样板代码)。但是,有时候我们想要在包级别指定的非空约束中解除一些字段(在包级别下排除一些非空的字段,让它们免于非空验证)。

4. @NonNullApi
@NonNullFields注解,顾名思义,它仅用于字段。如果我们想要在方法的参数和返回值上产生同样的效果,需要使用@NonNullApi注解。它的使用方法同@NonNullFields一样,需要配合package-info.java一起使用。下面两张图片表示出其用法,以后产生效果。

