我应该使用哪个@NotNull Java注释?| Java Debug 笔记
本文正在参加「Java主题月 - Java Debug笔记活动」,详情查看<活动链接>
提问:
我希望使我的代码更具可读性,并使用诸如IDE代码检查
和 / 或静态代码分析
(FindBugs和Sonar——这两个是检查代码规范的工具集,译者注)之类的工具来避免NullPointerExceptions
。许多工具似乎彼此互不兼容,在我的代码中列出了这些工具里的@NotNull
/ @NonNull
/ @Nonnull
注释,所有这些都很难读。你们有没有最佳的建议?这是我发现的等效注释的列表:
javax.validation.constraints.NotNull
创建用于运行时验证,而非静态分析。
注释文档edu.umd.cs.findbugs.annotations.NonNull
被 FindBugs (dead project) 和他的继承类 SpotBugs 静态分析和 Sonar (现在叫 Sonarqube)使用
javax.annotation.Nonnull
这可能也适用于FindBugs, 但是JSR-305 处于非活动状态(不太被很多人使用的意思*,*译者注)。 (也可以看如下资料: What is the status of JSR 305?) 源码org.jetbrains.annotations.NotNull
由IntelliJ IDEA IDE进行静态分析。
注释文档lombok.NonNull
在Project Lombok中用于控制代码生成。
占位符注释,因为没有标准。
源码, 注释文档android.support.annotation.NonNull
在Android中可用的标记注释,由support-annotations包提供
注释文档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.annotation
更好,它最终可能会与JSE一起出现,或者根本不会出现,那是有争议的问题。我个人更喜欢javax.annotation
,因为我不喜欢JEE依赖项。
这给我们留下了
javax.annotation
这也是最短的。
只有一种语法会更好:java.annotation.Nullable
。随着过去其他软件包从javax升级到java,javax.annotation
将是朝着正确方向迈出的一步。
执行
我希望它们都具有基本相同的琐碎实现,但是经过详细的分析表明,事实并非如此。
首先是相似之处:
@NonNull
批注都有一行:
1 | java复制代码public @interface NonNull {} |
除了:
org.jetbrains.annotations
将其称为@NotNull
并具有简单的实现- 具有更长实现的
javax.annotation
javax.validation.constraints
也称为@NotNull
并具有实现
@Nullable
annotations都有一行
1 | java复制代码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样式上下文。下表概述了:
1 | kotlin复制代码 FIELD METHOD PARAMETER LOCAL_VARIABLE |
org.eclipse.jdt.annotation
, javax.annotation
和 org.checkerframework.checker.nullness.qua
使用JLS 4.11中定义的上下文,我认为这是正确的方法。
这给我们留下了
javax.annotation
org.checkerframework.checker.nullness.qual
代码示例
为了帮助您自己比较更多详细信息,我在下面列出了每个注释的代码。为了使比较容易,我删除了注释,导入和@Documented
批注。 (除了Android包中的类之外,其他所有文件都具有@Documented
)。我对这些代码行和@Target
字段进行了重新排序,并进行了规范化。
1 | java复制代码package android.support.annotation; |
1 | java复制代码package edu.umd.cs.findbugs.annotations; |
1 | java复制代码package org.eclipse.jdt.annotation; |
1 | java复制代码package org.jetbrains.annotations; |
1 | java复制代码package javax.annotation; |
1 | java复制代码package org.checkerframework.checker.nullness.qual; |
为了完整起见,下面是@Nullable
实现:
1 | java复制代码package android.support.annotation; |
1 | java复制代码package edu.umd.cs.findbugs.annotations; |
1 | java复制代码package org.eclipse.jdt.annotation; |
1 | java复制代码package org.jetbrains.annotations; |
1 | java复制代码package javax.annotation; |
1 | java复制代码package org.checkerframework.checker.nullness.qual; |
以下两个软件包没有@Nullable
,因此我将它们分开列出;Lombox有一个很少用的@NonNul
。在javax.validation.constraints
中,@NonNull
实际上是一个@NotNull
,并且执行耗时很长。
1 | java复制代码package lombok; |
1 | java复制代码package javax.validation.constraints; |
支持
根据我的经验,Eclipse和Checker Framework至少是开箱即用地支持javax.annotation
。
总结
我理想的注释是Checker Framework实现的java.annotation
语法。
如果您不打算使用Checker Framework,则暂时最好还是使用javax.annotation
(JSR-305)。
如果您愿意尝试Checker Framework,请使用其org.checkerframework.checker.nullness.qual
。
用到的源码
android.support.annotation
fromandroid-5.1.1_r1.jar
edu.umd.cs.findbugs.annotations
fromfindbugs-annotations-1.0.0.jar
org.eclipse.jdt.annotation
fromorg.eclipse.jdt.annotation_2.1.0.v20160418-1457.jar
org.jetbrains.annotations
fromjetbrains-annotations-13.0.jar
javax.annotation
fromgwt-dev-2.5.1-sources.jar
org.checkerframework.checker.nullness.qual
fromchecker-framework-2.1.9.zip
lombok
fromlombok
commitf6da35e4c4f3305ecd1b415e2ab1b9ef8a9120b4
javax.validation.constraints
fromvalidation-api-1.0.0.GA-sources.jar
本文转载自: 掘金