我应该使用哪个@NotNull Java注解?

1317

我希望让我的代码更易读,并使用工具如IDE代码检查和/或静态代码分析(FindBugs和Sonar)来避免NullPointerException。许多工具似乎与彼此的@NotNull/@NonNull/@Nonnull注释不兼容,在我的代码中列出所有这些注释将非常难以阅读。有哪些推荐的“最佳”注释?以下是我找到的等效注释列表:


258
Apache 应该发明一个“通用”注解,并提供一个工具,可以将其转换为任何其他注解。解决过多标准的问题是发明一个新的标准。 - irreputable
10
如果 Apache 发明了一个新的“通用”工具,可能会有 56 个版本出现,且与其他项目重叠。而且,它也不一定是标准(标准≠普及)。最好使用真正标准的东西,比如 javax?.*。顺便说一下,在这些例子中并没有“太多标准”,我只看到了一个或两个。 - ymajoros
8
javax.annotation.Nonnull 可以与 findbugs 一起使用(我刚测试过),这是我使用它的一个有力理由。 - Nicolas C
26
如果我仅写@NotNull,则指的是com.sun.istack.internal.NotNull。天哪... - Thomas Weller
4
Optionals可以在你以前使用空对象(NullObjects)的情况下非常有用。但它们并没有像运行时的@NotNull注释那样解决相同的问题,而且它们会导致繁琐的解包过程。 - Dave
显示剩余11条评论
25个回答

4

如果您正在开发Android应用程序,您会在某种程度上与Eclipse(编辑:在撰写本文时不再如此)联系在一起,它具有自己的注释。 它包含在Eclipse 3.8+(Juno)中,但默认情况下被禁用。

您可以在“首选项”>“Java”>“编译器”>“错误/警告”>“空分析”(底部可折叠部分)中启用它。

勾选“启用基于注释的空值分析”

http://wiki.eclipse.org/JDT_Core/Null_Analysis#Usage提供了设置建议。然而,如果您的工作区中有外部项目(如Facebook SDK),它们可能不符合这些建议,并且您可能不想在每次SDK更新时都修复它们;-)

我使用:

  1. 空指针访问:错误
  2. 违反空规范:错误(链接到点#1)
  3. 潜在空指针访问:警告(否则Facebook SDK将出现警告)
  4. 空注释和空推理之间的冲突:警告(链接到点#3)

5
与“日食”有关吗?不是真的。 - dcow
1
@DavidCowden IntelliJ IDEA支持Android开发,我认为是在Android Studio推出之前就已经可用了。 - Mārtiņš Briedis
@MārtiņšBriedis 是的,没错。我想你是指 @chaqke - dcow
值得注意的是,Android和IntelliJ具有不同的注释,并且在Java包含官方注释之前,这种情况可能会持续下去。以下是使用Eclipse注释的说明。 - chaqke
它从来没有依赖于Eclipse。你可以使用任何你想要的IDE。 - DennisK
Java在Java 8之前没有自己的注释(https://dev59.com/62445IYBdhLWcg3wQX6G#4963420)。在此之前,Eclipse和IntelliJ都有自己的实现,彼此不兼容。这个答案与Eclipse相关;而IntelliJ则在这里解释了如何使用它们的:http://www.jetbrains.com/idea/documentation/howto.html,当然你可以使用任何工具 :-) - chaqke

3
如果您正在使用Spring 5.x / SpringBoot 2.x,您应该绝对使用Spring注释(org.springframework.lang),因为它们为您提供了一个默认的包范围空值检查,具体表现为注释@NonNullFields@NonNullApi。由于您使用的是@NonNullFields/@NonNullApi,您甚至不会与其他依赖项中的NotNull/NonNull注释发生冲突。这些注释必须在名为package-info.java的文件中使用,该文件位于包的根目录中:
@NonNullFields
@NonNullApi
package org.company.test;

为了从空值检查中排除某些字段、参数或返回值,只需显式使用@Nullable注释。您也可以在所有地方使用@NonNull,而不是使用@NonNullFields/@NonNullApi,但可能最好默认情况下使用@NonNullFields/@NonNullApi激活空值检查,只对特定的异常使用@Nullable
IDE(Intellij)将突出显示违反空条件的代码。如果设置正确,每个开发人员都可以假设字段、参数和返回值必须不为null,除非有@Nullable注释。有关更多信息,请查看此文章

谢谢您提供的信息。我已将这些添加到多个包中,但是当我传递空值时,我没有看到任何警告。 - undefined

2

11
我不知道它是什么,但软件包的名称应该是一个很大的线索,表明它并不适用于一般用途。 - Stephen C
3
通常情况下,人们会避免使用com.sun命名空间中的类,因为它们是内部的,不适合直接使用,并且没有任何保证其将来可用性或行为。除非有非常充分的理由,否则不应该直接使用com.sun的组件。 - luis.espinal
加上在Java2s.com上呈现出如此糟糕的HTML格式,这应该会引起你的警觉 :) - luis.espinal

2

1
另一个选择是使用ANTLR 4提供的注释。根据Pull Request #434,包含@NotNull@Nullable注释的工件包括一个注释处理器,如果这些属性之一被错误使用(例如,如果两者都应用于同一项,或者如果@Nullable应用于具有原始类型的项),则会生成编译时错误和/或警告。注释处理器在软件开发过程中提供了额外的保证,以确保这些注释的应用传达的信息是准确的,包括方法继承的情况。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接