我希望使我的代码更具可读性,以及使用工具,如IDE代码检查和/或静态代码分析(FindBugs和Sonar),以避免nullpointerexception。许多工具似乎与彼此的@NotNull/@NonNull/ @NonNull注释不兼容,在我的代码中列出所有这些工具会让人难以阅读。有没有什么建议,哪一个是“最好的”?下面是我找到的等价注释列表:

javax.validation.constraints.NotNull Created for runtime validation, not static analysis. documentation edu.umd.cs.findbugs.annotations.NonNull Used by FindBugs (dead project) and its successor SpotBugs static analysis and therefore Sonar (now Sonarqube) FindBugs documentation, SpotBugs documentation javax.annotation.Nonnull This might work with FindBugs too, but JSR-305 is inactive. (See also: What is the status of JSR 305?) source org.jetbrains.annotations.NotNull Used by IntelliJ IDEA IDE for static analysis. documentation lombok.NonNull Used to control code generation in Project Lombok. Placeholder annotation since there is no standard. source, documentation androidx.annotation.NonNull Marker annotation available in Android, provided by annotation package documentation org.eclipse.jdt.annotation.NonNull Used by Eclipse for static code analysis documentation


当前回答

安卓

这个答案是Android特有的。Android有一个支持包叫做support-annotations。它提供了几十个Android特定的注释,也提供了常见的注释,如NonNull, Nullable等。

要添加support-annotations包,在build.gradle中添加以下依赖项:

compile 'com.android.support:support-annotations:23.1.1'

然后使用:

import android.support.annotation.NonNull;

void foobar(@NonNull Foo bar) {}

其他回答

如果你在做一个大项目,你最好创建自己的@Nullable和/或@NotNull注解。

例如:

@java.lang.annotation.Documented
@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS)
@java.lang.annotation.Target({java.lang.annotation.ElementType.FIELD,
                              java.lang.annotation.ElementType.METHOD,    
                              java.lang.annotation.ElementType.PARAMETER,
                              java.lang.annotation.ElementType.LOCAL_VARIABLE})
public @interface Nullable 
{
}

如果您使用了正确的保留策略,那么注释在运行时将不可用。从这个角度来看,它只是一种内在的东西。

尽管这不是一门严格的科学,但我认为使用内部类是最有意义的。

这是一个内在的东西。(没有功能或技术影响) 有很多很多的用法。 像IntelliJ这样的IDE支持自定义的@Nullable/@NotNull注释。 大多数框架也喜欢使用自己的内部版本。

其他问题(见评论):

如何在IntelliJ中配置这个?

点击IntelliJ状态栏右下角的“警官”。在弹出窗口中单击“配置巡检”。下一个……

JSR305和FindBugs是由同一个人编写的。两者的维护都很差,但都是标准的,并且得到所有主要ide的支持。好消息是,他们工作得很好。

下面是如何在默认情况下将@Nonnull应用到所有类、方法和字段。 参见https://stackoverflow.com/a/13319541/14731和https://stackoverflow.com/a/9256595/14731

定义@NotNullByDefault

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import javax.annotation.Nonnull;
import javax.annotation.meta.TypeQualifierDefault;


    /**
     * This annotation can be applied to a package, class or method to indicate that the class fields,
     * method return types and parameters in that element are not null by default unless there is: <ul>
     * <li>An explicit nullness annotation <li>The method overrides a method in a superclass (in which
     * case the annotation of the corresponding parameter in the superclass applies) <li> there is a
     * default parameter annotation applied to a more tightly nested element. </ul>
     * <p/>
     * @see https://stackoverflow.com/a/9256595/14731
     */
    @Documented
    @Nonnull
    @TypeQualifierDefault(
    {
        ElementType.ANNOTATION_TYPE,
        ElementType.CONSTRUCTOR,
        ElementType.FIELD,
        ElementType.LOCAL_VARIABLE,
        ElementType.METHOD,
        ElementType.PACKAGE,
        ElementType.PARAMETER,
        ElementType.TYPE
    })
    @Retention(RetentionPolicy.RUNTIME)
    public @interface NotNullByDefault
    {
    }

2. 将注释添加到每个包:package-info.java

@NotNullByDefault
package com.example.foo;

更新:截至2012年12月12日,JSR 305被列为“休眠”。根据文档:

被执行委员会投票为“休眠”的JSR,或者已经达到自然生命周期的JSR。

看起来JSR 308正在加入JDK 8,尽管JSR没有定义@NotNull,但是附带的Checkers框架定义了。在撰写本文时,由于这个错误,Maven插件无法使用:https://github.com/typetools/checker-framework/issues/183

如果您正在使用Spring 5。2.执行以下命令:你应该使用Spring注释(org.springframework.lang),因为它们通过@NonNullFields和@NonNullApi注解为你提供了默认的包范围的null检查。当你使用@NonNullFields/@NonNullApi时,你甚至不会与来自其他依赖的其他NotNull/NonNull注释发生冲突。注释必须用在一个名为package-info.java的文件中,该文件位于包的根目录下:

@NonNullFields
@NonNullApi
package org.company.test;

要排除null检查中的某些字段、参数或返回值,只需显式地使用@Nullable注释。而不是使用@NonNullFields/@NonNullApi,你也可以在任何地方设置@NonNull,但可能更好的是在默认情况下使用@NonNullFields/@NonNullApi激活null检查,并且只使用@Nullable执行特定的异常。

IDE (Intellij)将突出显示违反null条件的代码。如果设置正确,每个开发人员都可以假设字段、参数和返回值必须不是空,除非有@Nullable注释。要了解更多信息,请查看这篇文章。

不幸的是,JSR 308将不会添加比这个项目本地非空建议更多的值

Java 8将不会提供单一的默认注释或自己的Checker框架。 类似于Find-bugs或JSR 305,这个JSR由一小群主要是学术团队维护得很差。

它背后没有商业力量,因此JSR 308现在发布EDR 3 (JCP的早期草案审查),而Java 8应该在不到6个月内发布:-O 顺便说一句,类似于310。但与308不同的是,Oracle现在已经从其创始人手中接管了这一业务,以最大限度地减少它对Java平台的伤害。

每个项目、供应商和学术类,比如检查器框架和JSR 308背后的那些,都将创建自己的专有检查器注释。

让源代码在未来几年不兼容,直到找到一些流行的妥协,并可能添加到Java 9或10中,或者通过Apache Commons或谷歌Guava这样的框架;-)

如果你正在为android开发,那么你在某种程度上与Eclipse(编辑:在撰写本文时,不再)有一定的联系,它有自己的注释。它包含在Eclipse 3.8+ (Juno)中,但默认禁用。

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

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

http://wiki.eclipse.org/JDT_Core/Null_Analysis#Usage有关于设置的建议。然而,如果你的工作空间中有外部项目(如facebook SDK),它们可能不满足这些建议,你可能不想在每次SDK更新时修复它们;-)

我使用:

空指针访问:错误 违反空规范:错误(链接到第1点) 潜在的空指针访问:警告(否则facebook SDK将有警告) 空注释和空推断之间的冲突:警告(链接到第3点)