当前位置: 首页 > 科技观察

NullinSpring我敢打赌你不知道这些事情

时间:2023-03-14 12:44:07 科技观察

之前在一些代码中看到过@Nullable标注的注解,当时没在意它是什么意思,所以忍不住查了下待会儿,这篇文章会讲讲Spring中Null的那些事。在Java中,不允许使用类型来表示它的空安全性,但是SpringFramework现在在org.springgframework.lang包中提供了如下注解来声明API和字段的可空性:@Nullable:用于指定参数,returnvalues或field可以注释为null。@NonNull:与上述注解相反,表示指定的参数、返回值或字段不允许为null。(@NonNullApi和@NonNullFields适用的参数/返回值和字段不是必须的)@NonNullApi:声明非空作为参数和返回值的包级注解。@NonNullFields:包级注解声明字段默认为非空。SpringFramework本身使用上述注释,但它们也可以用于任何基于Spring的Java项目来声明空的安全api和空的安全字段。尚不支持数组元素的泛型和可空性,但应该在以后的版本中支持。SpringNull-Safety在Spring5中出现,让我们编写null-safe代码变得更加简单。这称为空安全。Null-safety不允许我们转义不安全的代码,但会在编译时产生警告。此类警告可防止在运行时发生灾难性的空指针异常(NPE)。@NonNull@NonNull注释是所有空值安全注释中最重要的。我们可以使用此注释在任何需要对象引用的地方声明非空约束:字段、方法参数或方法返回值。我们先来看一个例子publicclassStudent{privateStringname;publicStringgetName(){returnname;}publicvoidsetName(Stringname){if(null!=null&&name.isEmpty()){name=null;}this.name=name;}}上面的代码是为了name验证有效,但是有一个缺陷,如果name设置为null,那么当我们使用name的时候,就会以NullPointerException结束。使用@NonNullSpring的null-safety特性可以让idea或eclipse报告这种潜在的威胁。比如我们用IDEA给属性加上@NonNull,就会出现如下效果。奇怪,没有变化。我没有看到任何潜在的安全提示。那是你没有想好。设置安全检查如果没有提示,可以通过以下方式设置安全检查:如果不好用,那么在右边的配置注解中添加@NonNull和@Nullable所在的jar包,如下:添加,Type?可以看到如下效果。现在fullName已经被@NonNull注解添加编译器来检查空值!测试一下,可以把@NonNull注释去掉,鼠标放在fullName上就不会出现这个提示了。@NonNullFields@NonNull注释可以帮助您确保空值安全。但是,如果这个注解直接装饰所有的字段,就会污染整个代码库。Spring提供了另一个不允许null的注解——@NonNullFields。这个注解适合在包级别使用,通知我们的开发工具对包中的所有字段进行注解。默认不允许为null新建一个Parent类,在该类所属的包下创建一个名为package-info.java的包。类,不是Java类,而是创建的文件,名为package-info.java,如下:package-info.java@NonNullFieldspackagecom.nullsafety.demo.pojo;importorg.springframework.lang.NonNullFields;创建一个新的Parent.java类(age!=null&&age.isEmpty()){age=null;}this.age=age;}publicvoidsetName(Stringname){if(name!=null&&name.isEmpty()){name=null;}this.name=name;}}package-info@NonNullFieldsin.java可以处理父类中的所有属性。将鼠标放在任何属性上,都会出现编译时检查的提示@Nullable@NonNullFields注解通常比@NonNull更好,因为它有助于减少样板代码。然而,有时我们希望免除某些字段在包级别指定的非空约束。这时候我们就要用@Nullable注解来修改Person.java。Person.java和pack-info.java在同一个包中publicclassPerson{@NonNullprivateStringfullName;@NullableprivateStringnickName;publicStringgetNickName(){returnnickName;}publicvoidsetNickName(StringnickName){if(nickName!=null&&nickName.isEmpty()){nickName=null;}this.nickName=nickName;}publicStringgetFullName(){returnfullNameset;}publicvoid(StringfullName){if(fullName!=null&&fullName.isEmpty()){fullName=null;}this.fullName=fullName;}}在这种情况下,我们使用@Nullable注释来覆盖字段上@NonNullFields的语义。@NonNullApi@NonNullFields注释仅适用于其名称指示的字段。如果我们想对方法的参数和返回值产生同样的效果,我们需要@NonNullApi。在configure注解中添加@NonNullApi和@NonNullFields,选择NonNullApi为@NonNullFields,我们需要在package-info.java中定义@NonNullApipackage-info.java@NonNullApi@NonNullFieldspackagecom.nullsafety.demo.pojo;importorg.springframework。lang.NonNullApi;importorg.springframework.lang.NonNullFields;添加如下注释后,效果如下:返回值时可以在编译时收到提示。结论看完文章,你至少应该了解@NonNull、@Nullable、@NonNullFields、@NonNullApi这四个注解及其各自的作用域,以及如何在编译时设置Null-safety检查。