本文正在参加「Java主题月 – Java Debug笔记活动」,详情查看活动链接
我应该使用哪个@NotNull Java注释?
我希望使我的代码更具可读性,并使用诸如IDE代码检查和/或静态代码分析(FindBugs和Sonar)之类的工具来避免NullPointerExceptions。许多工具似乎彼此不兼容,并且@NotNull/ @NonNull/@Nonnull注解在我的代码中列出所有工具都很难读。关于哪个是“最佳”的任何建议?这是我发现的等效注释的列表:
javax.validation.constraints.NotNull
创建用于运行时验证,而非静态分析。
文件资料
edu.umd.cs.findbugs.annotations.NonNull
由FindBugs(无效项目)及其后续SpotBugs静态分析使用,因此也用于Sonar(现在为Sonarqube)
FindBugs文档,SpotBugs文档
javax.annotation.Nonnull
这可能也可以与FindBugs一起使用,但是JSR-305处于非活动状态。(另请参见:JSR 305的状态是什么?) 来源
org.jetbrains.annotations.NotNull
由IntelliJ IDEA IDE进行静态分析。
文件资料
lombok.NonNull
用于控制Lombok项目中的代码生成。
占位符注释,因为没有标准。
源,文档
android.support.annotation.NonNull
由支持注释包文档提供的Android中可用的标记注释
org.eclipse.jdt.annotation.NonNull
Eclipse用于静态代码分析
复制代码
高分回答:
由于JSR 305(其目的是规范@NonNull和@Nullable)已经蛰伏了好几年,恐怕也没有很好的答案。我们所能做的就是找到一个务实的解决方案,我的方法如下:
句法
从纯粹的风格角度来看,除了Java本身,我想避免引用任何IDE,框架或任何工具包。
这排除了:
android.support.annotation
edu.umd.cs.findbugs.annotations
org.eclipse.jdt.annotation
org.jetbrains.annotations
org.checkerframework.checker.nullness.qual
lombok.NonNull
复制代码
这给我们留下了javax.validation.constraints或javax.annotation。前者带有JEE。如果这比javax.annotationJSE更好,那么JSE最终可能会发布它,或者根本不会发布它,这是有争议的问题。我个人更喜欢,javax.annotation因为我不喜欢JEE依赖项。
这给我们留下了
javax.annotation
这也是最短的。
只有一个语法甚至会更好:java.annotation.Nullable。至于其他的包,从毕业javax到java在过去,javax.annotation中是朝着正确方向迈出的一步。
执行
我希望它们都具有基本相同的琐碎实现,但是经过详细的分析表明,事实并非如此。
首先是相似之处:
该@NonNull注释都行
public @interface NonNull {}
除了
org.jetbrains.annotations调用它@NotNull并实现一个简单的实现
javax.annotation 实施时间更长
javax.validation.constraints也称为它@NotNull并有一个实现
复制代码
该@Nullable注释都行
public @interface Nullable {}
复制代码
除了(再次)org.jetbrains.annotations采用微不足道的实现。
对于差异:
引人注目的是
javax.annotation
javax.validation.constraints
org.checkerframework.checker.nullness.qual
复制代码
都具有运行时注释(@Retention(RUNTIME)),而
android.support.annotation
edu.umd.cs.findbugs.annotations
org.eclipse.jdt.annotation
org.jetbrains.annotations
复制代码
只是编译时间(@Retention(CLASS))。
如本所述,运行时批注的影响比人们想象的要小,但是它们的好处是,除编译时外,还使工具能够执行运行时检查。
另一个重要的区别是注释可以在代码中的何处使用。有两种不同的方法。一些软件包使用JLS 9.6.4.1样式上下文。下表概述了:
android.support.annotation XXX
edu.umd.cs.findbugs.annotations XXXX
org.jetbrains.annotation XXXX
lombok XXXX
javax.validation.constraints XXX
org.eclipse.jdt.annotation,javax.annotationorg.checkerframework.checker.nullness.qual使用JLS 4.11中定义的上下文,我认为这是正确的方法。
这给我们留下了
javax.annotation
org.checkerframework.checker.nullness.qual
复制代码
高分回答:
Spring 5在程序包级别具有@NonNullApi。对于已经具有Spring依赖项的项目来说,这似乎是一个方便的选择。所有字段,参数和返回值默认为@NonNull,而@Nullable可以在几个不同的地方应用。
文件package-info.java:
@org.springframework.lang.NonNullApi
package com.acme;
复制代码
文章翻译自 yl2gl72eozkinivz3vc6swkesy-ac4c6men2g7xr2a-translate.translate.goog/questions/4…
作者建议:高分答案还有一块代码我没有贴出。在这里作者主要用的是spring的Validated,我觉得是比较好用的
@RequestMapping("/version")
public BaseResponse version(@Validated @VNotNull(name = "xxID") Long oId,
@Validated @VNotBlank(name = "xxx当前版本") String xxVersion) {
return BaseResponse.success(appVersionService.checkAndGetNewVersion(orgId, appVersion));
}
复制代码
在检测到参数为null会自动抛出异常,并补全信息,例如“xxx当前版本不能为空”
真心感谢帅逼靓女们能看到这里,如果这个文章写得还不错,觉得有点东西的话
求点赞? 求关注❤️ 求分享? 对8块腹肌的我来说真的 非常有用!!!
如果本篇博客有任何错误,请批评指教,不胜感激 !❤️❤️❤️❤️