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

Which @NotNull Java annotation should I use?

我希望使我的代码更可读,并使用诸如IDE代码检查和/或静态代码分析(findbugs和sonar)之类的工具来避免nullpointerException。许多工具似乎与彼此的@NotNull@NonNull@NonNull@NonNull注释不兼容,在我的代码中列出所有这些工具都是很难阅读的。有什么建议是"最好"的吗?以下是我找到的等效注释列表:

  • javax.validation.constraints.NotNull创建用于运行时验证,而不是静态分析。文档

  • edu.umd.cs.findbugs.annotations.NonNull用于findbugs静态分析,因此是声纳(现在是声纳管)文档

  • javax.annotation.Nonnull这可能也适用于findbugs,但JSR-305是非活动的。(另请参见:JSR 305的状态是什么?)来源

  • org.jetbrains.annotations.NotNullIntellij IDEA IDE用于静态分析。文档

  • lombok.NonNull用于控制Lombok项目中的代码生成。占位符注释,因为没有标准。源,文档

  • android.support.annotation.NonNullAndroid中提供的标记注释,由支持注释包提供文档

  • org.eclipse.jdt.annotation.NonNullEclipse用于静态代码分析文档


由于Oracle目前决定不标准化@nonnull(和@nullable),恐怕没有好的答案。我们所能做的就是找到一个实用的解决方案,我的方法如下:好的。句法

从纯风格的观点来看,我希望避免引用IDE、框架或任何工具包,除了Java本身。好的。

这就排除了:好的。

  • android.support.annotation(安卓支持注释)
  • edu.umd.cs.findbugs.annotations.注释
  • org.eclipse.jdt.annotation注释
  • org.jetbrains.annotations.注释
  • org.checkerframework.checker.nullness.qual
  • LoBOBK.NONLULL

这会给我们留下javax.validation.constraints或javax.annotation。前者和jee一起。如果这比javax.annotation更好的话,这将是一个有争议的问题,而javax.annotation最终可能会随JSE一起出现,或者根本不会出现。我个人更喜欢javax.annotation,因为我不喜欢jee依赖。好的。

这让我们好的。

javax.注释好的。

这也是最短的一个。好的。

只有一种语法更好:java.annotation.nullable。随着其他包裹的逐渐增多从过去的Javax到Java,JavaX.注释将朝着正确的方向迈出一步。好的。实施

我希望它们都有基本相同的小实现,但一份详细的分析表明这不是真的。好的。

首先是相似之处:好的。

@nonnull注释都有行好的。

1
public @interface NonNull {}

除了好的。

  • org.jetbrains.annotations,它调用@notnull并有一个简单的实现
  • javax.annotation实现更长
  • javax.validation.constraints,它还调用它@notnull并有一个实现

@nullable注释都有行好的。

1
public @interface Nullable {}

除了(再次)org.jetbrains.annotations及其简单的实现。好的。

对于差异:好的。

最引人注目的是好的。

  • javax.注释
  • 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
2
3
4
5
6
                                FIELD   METHOD  PARAMETER LOCAL_VARIABLE
android.support.annotation      X       X       X  
edu.umd.cs.findbugs.annotations X       X       X         X
org.jetbrains.annotation        X       X       X         X
lombok                          X       X       X         X
javax.validation.constraints    X       X       X

org.eclipse.jdt.annotation、javax.annotation和org.checkerFramework.checker.nullness.qual使用中定义的上下文JLS 4.11,我认为这是正确的方法。好的。

这让我们好的。

  • javax.annotation
  • org.checkerframework.checker.nullness.qual

在这轮。

代码

帮助你自己比较进一步的细节在下面的代码的注释列表。让我比较容易被删除的评论和注释,进口记录"。(他们都有"类的研究除了从Android包)。我的目标reordered线场和标准化"和"资格。

1
2
3
4
package android.support.annotation;
@Retention(CLASS)
@Target({FIELD, METHOD, PARAMETER})
public @interface NonNull {}
1
2
3
4
package edu.umd.cs.findbugs.annotations;
@Retention(CLASS)
@Target({FIELD, METHOD, PARAMETER, LOCAL_VARIABLE})
public @interface NonNull {}
1
2
3
4
package org.eclipse.jdt.annotation;
@Retention(CLASS)
@Target({ TYPE_USE })
public @interface NonNull {}
1
2
3
4
package org.jetbrains.annotations;
@Retention(CLASS)
@Target({FIELD, METHOD, PARAMETER, LOCAL_VARIABLE})
public @interface NotNull {String value() default"";}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package javax.annotation;
@TypeQualifier
@Retention(RUNTIME)
public @interface Nonnull {
    When when() default When.ALWAYS;
    static class Checker implements TypeQualifierValidator<Nonnull> {
        public When forConstantValue(Nonnull qualifierqualifierArgument,
                Object value) {
            if (value == null)
                return When.NEVER;
            return When.ALWAYS;
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package org.checkerframework.checker.nullness.qual;
@Retention(RUNTIME)
@Target({TYPE_USE, TYPE_PARAMETER})
@SubtypeOf(MonotonicNonNull.class)
@ImplicitFor(
    types = {
        TypeKind.PACKAGE,
        TypeKind.INT,
        TypeKind.BOOLEAN,
        TypeKind.CHAR,
        TypeKind.DOUBLE,
        TypeKind.FLOAT,
        TypeKind.LONG,
        TypeKind.SHORT,
        TypeKind.BYTE
    },
    literals = {LiteralKind.STRING}
)
@DefaultQualifierInHierarchy
@DefaultFor({TypeUseLocation.EXCEPTION_PARAMETER})
@DefaultInUncheckedCodeFor({TypeUseLocation.PARAMETER, TypeUseLocation.LOWER_BOUND})
public @interface NonNull {}

这里是"完整的"将实现:

1
2
3
4
package android.support.annotation;
@Retention(CLASS)
@Target({METHOD, PARAMETER, FIELD})
public @interface Nullable {}
1
2
3
4
package edu.umd.cs.findbugs.annotations;
@Target({FIELD, METHOD, PARAMETER, LOCAL_VARIABLE})
@Retention(CLASS)
public @interface Nullable {}
1
2
3
4
package org.eclipse.jdt.annotation;
@Retention(CLASS)
@Target({ TYPE_USE })
public @interface Nullable {}
1
2
3
4
package org.jetbrains.annotations;
@Retention(CLASS)
@Target({FIELD, METHOD, PARAMETER, LOCAL_VARIABLE})
public @interface Nullable {String value() default"";}
1
2
3
4
5
package javax.annotation;
@TypeQualifierNickname
@Nonnull(when = When.UNKNOWN)
@Retention(RUNTIME)
public @interface Nullable {}
1
2
3
4
5
6
7
8
9
10
package org.checkerframework.checker.nullness.qual;
@Retention(RUNTIME)
@Target({TYPE_USE, TYPE_PARAMETER})
@SubtypeOf({})
@ImplicitFor(
    literals = {LiteralKind.NULL},
    typeNames = {java.lang.Void.class}
)
@DefaultInUncheckedCodeFor({TypeUseLocation.RETURN, TypeUseLocation.UPPER_BOUND})
public @interface Nullable {}

下面的两个软件包没有"可空,所以他们的菜单列表龙目岛有一个非空的很无聊"。在javax.validation.constraints"实际上是"非空"notnull a它有一longish实现。

1
2
3
4
package lombok;
@Retention(CLASS)
@Target({FIELD, METHOD, PARAMETER, LOCAL_VARIABLE})
public @interface NonNull {}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package javax.validation.constraints;
@Retention(RUNTIME)
@Target({ FIELD, METHOD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
@Constraint(validatedBy = {})
public @interface NotNull {
    String message() default"{javax.validation.constraints.NotNull.message}";
    Class<?>[] groups() default { };
    Class<? extends Payload>[] payload() default {};
    @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
    @Retention(RUNTIME)
    @Documented
    @interface List {
        NotNull[] value();
    }
}

支持

我的体验是javax.annotation形式至少支持框架Eclipse和格子的盒子。

摘要

我的理想是java.annotation注释的语法与格子框架的实现。

如果你不打算使用的格子框架javax.annotation(JSR - 305)仍然是你最好的赌注是对的时间。

如果你愿意购买到格子框架只是使用他们的org.checkerframework.checker.nullness.qual。

来源

  • 从Android android.support.annotation 5.1.1 _ r1.jar
  • 从findbugs-annotations-1.0.0.jar edu.umd.cs.findbugs.annotations
  • 从org.eclipse.jdt.annotation _ 2.1.0.v20160418-1457.jar org.eclipse.jdt.annotation
  • 从jetbrains-annotations-13.0.jar org.jetbrains.annotations
  • 从gwt-dev-2.5.1-sources.jar javax.annotation
  • 从checker-framework-2.1.9.zip org.checkerframework.checker.nullness.qual
  • 龙目岛和龙目岛提交f6da35e4c4f3305ecd1b415e2ab1b9ef8a9120b4
  • 从validation-api-1.0.0.ga-sources.jar javax.validation.constraints

好的。


我非常喜欢checker框架,它是类型注释(JSR-308)的一个实现,用于实现缺陷检查程序,比如nullness检查程序。我没有尝试过其他人提供任何比较,但我对这个实现很满意。

我不属于提供软件的小组,但我是一个粉丝。

我喜欢这个系统的四件事:

  • 它有一个用于空性(@nullable)的缺陷检查程序,但也有一个用于不可变性和中间性(以及其他)的缺陷检查程序。我使用第一个(空值),并且尝试使用第二个(不可变/igj)。我正在尝试第三个,但我还不确定是否要长期使用它。我还不相信其他检查程序的一般用途,但是很高兴知道框架本身是一个实现各种附加注释和检查程序的系统。

  • 空度检查的默认设置工作良好:非空,除了局部变量(nnel)。基本上,这意味着默认情况下,检查器将除局部变量之外的所有变量(实例变量、方法参数、泛型类型等)视为默认的@nonnull类型。根据文件:


    The NNEL default leads to the smallest number of explicit annotations in your code.

    如果NNEL不适合您,您可以为类或方法设置不同的默认值。

  • 此框架允许您在不创建对框架的依赖性的情况下使用,方法是将注释括在注释中:例如/*@Nullable*/。这很好,因为您可以对库或共享代码进行注释和检查,但仍然可以在另一个不使用框架的项目中使用该库/共享代码。这是一个很好的功能。我已经习惯了使用它,即使我现在倾向于在我的所有项目上启用检查器框架。

  • 框架有一种方法来注释您使用的API,这些API还没有通过使用存根文件为空进行注释。


  • 我使用Intellij,因为我主要关注Intellij标记可能产生NPE的事物。我同意在JDK中没有标准注释是令人沮丧的。有人说添加它,它可能会进入Java 7。在这种情况下,还有一个选择!


    根据Java 7特性列表,JSR308类型注解被推迟到Java 8。甚至没有提到JSR-305注释。

    在最新的JSR-308草案的附录中有一些关于JSR-305状态的信息。这包括观察到JSR-305注释似乎被放弃了。JSR-305页面还将其显示为"非活动"。

    同时,语用的答案是使用最广泛使用的工具支持的注释类型…如果情况发生变化,要做好改变的准备。

    事实上,JSR-308没有定义任何注释类型/类,看起来它们认为它超出了范围。(考虑到JSR-305的存在,他们是对的)。

    但是,如果JSR308看起来像是进入Java 8,如果JSR305的兴趣恢复了,我也不会感到惊讶。阿法克,JSR-305小组还没有正式放弃他们的工作。他们已经安静了2年多了。

    有趣的是,Bill Pugh(JSR-305的技术负责人)是findbugs背后的人之一。


    对于机器人项目,你应该使用android.support.annotation.NonNullandroid.support.annotation.Nullable。这些及其他辅助性的Android-specific annotations可在支持图书馆查阅。

    From http://tools.android.com/tech-docs/support-annotations:

    The support library itself has also been annotated with these
    annotations, so as a user of the support library, Android Studio will
    already check your code and flag potential problems based on these
    annotations.


    如果任何人只是在寻找智力阶级:你可以带他们去圣母院休息。

    1
    2
    3
    4
    5
    <dependency>
        <groupId>org.jetbrains</groupId>
        annotations</artifactId>
        <version>15.0</version>
    </dependency>


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

    以下是默认情况下如何将@nonnull应用于所有类、方法和字段。请参阅https://stackoverflow.com/a/13319541/14731和https://stackoverflow.com/a/9256595/14731

  • 定义@NotNullByDefault
  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    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

    1
    2
    @NotNullByDefault
    package com.example.foo;

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

    A JSR that was voted as"dormant" by the Executive Committee, or one that has reached the end of its natural lifespan.

    看起来JSR 308正在将其转换成JDK 8,虽然JSR没有定义@notnull,但附带的Checkers Framework定义了它。在撰写本文时,由于此错误,Maven插件不可用:https://github.com/typetools/checker-framework/issues/183


    Eclipse也有自己的注释。

    1
    org.eclipse.jdt.annotation.NonNull

    有关详细信息,请参阅http://wiki.eclipse.org/jdt_core/null_analysis。


    只需指出Java验证API(EDCOX1,3×)不带有EDCOX1,1注释,这在静态分析上下文中是非常有价值的。运行时bean验证是有意义的,因为这是Java中任何非原始字段的默认(即没有验证/强制执行)。出于所述目的,应权衡备选方案。


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

    Java 8不附带单个默认注释或其自己的Checker框架。与查找bug或JSR 305类似,这个JSR由一小部分主要是学术团队维护得很差。

    因此,JSR 308现在启动了EDR 3(JCP的早期草案审查),而Java 8预计在不到6个月的时间内发货:-o类似于EDCOX1,16,BTW。但是与EDCOX1不同,17的AID已经接管了它的创建者,以减少对Java平台的危害。

    每个项目、供应商和学术类,如Checker FrameworkJSR 308后面的项目、供应商和学术类,都将创建自己的专有检查器注释。

    使源代码在未来几年内不兼容,直到找到一些流行的折衷方案,并可能添加到Java 910,或通过类似Apache CommonsGoogle Guava的框架;-)


    仙女座

    这个答案是安卓特异的。安德罗德支持包装称为EDOCX1。这是安卓特异性注释的一部分,也提供了类似于EDOCX1的共同点。

    To add support-annotations package,add the following dependency in your build.gradle:

    ZZU1

    然后使用:

    1
    2
    3
    import android.support.annotation.NonNull;

    void foobar(@NonNull Foo bar) {}

    区分静态分析和运行时分析。对内部内容使用静态分析,对代码的公共边界使用运行时分析。

    对于不应为空的内容:

    • 运行时检查:使用"if(x==null)…"(零依赖项)或@javax.validation.notnull(带bean验证)或@lombok.nonnull(简单明了)或guavas preconditions.checknotnull(…)

      • 对方法返回类型使用可选(仅限)。Java8或Guava。
    • 静态检查:使用@nonnull注释

    • 在合适的地方,在类或包级别上使用@…非空的默认注释。自己创建这些注释(很容易找到示例)。
      • 否则,在方法返回时使用@…checkfornull以避免NPE

    这将产生最好的结果:IDE中的警告、findbugs和checkerframework的错误、有意义的运行时异常。

    不要期望静态检查成熟,它们的命名没有标准化,不同的库和IDE对它们的处理不同,忽略它们。jsr305 javax.annotations.*类看起来像标准的,但它们不是标准的,它们会导致使用java9+拆分包。

    一些注释说明:

    • findbugs/spotbugs/jsr305注释与包javax.validation.*与java9+中的其他模块冲突,也可能违反Oracle许可证
    • spotbugs注释仍然依赖于编译时的jsr305/findbugs注释(在编写https://github.com/spotbugs/spotbugs/issues/421时)
    • jetbrains@notnull名称与@javax.validation.notnull冲突。
    • 与javax.annotations相比,用于静态检查的JetBrains、Eclipse或CheckersFramework注释具有优势,即它们不会与java9及更高版本中的其他模块冲突。
    • @nullable并不意味着查找你(或你的IDE)认为它意味着什么。findbugs将忽略它(在成员上)。悲伤,但真实(https://sourceforge.net/p/findbugs/bugs/1181)
    • 对于一个IDE外部的静态检查,存在两个自由工具:spotbugs(以前是findbugs)和checkersframework。
    • Eclipse库默认为@nonNullBy,JSR305仅默认为@ParametersAreonNullBy。这些仅仅是将基本注释应用于包(或类)中的所有内容的方便包装器,您可以轻松地创建自己的注释。这可用于包装。这可能与生成的代码(例如Lombok)冲突。
    • EclipseJDT注释不适用于静态方法返回和其他一些情况。
    • 对于与其他人共享的库,应避免使用lombok作为导出依赖项,传递依赖项越少越好。
    • 使用bean验证框架是强大的,但是需要很高的开销,所以这是为了避免手动的空检查而造成的。
    • 对字段和方法参数使用可选是有争议的(您可以很容易地找到有关它的文章)
    • android空注释是android支持库的一部分,它们与许多其他类一起提供,并且不能很好地与其他注释/工具一起使用。

    在Java9之前,这是我的建议:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    // file: package-info.java
    @javax.annotation.ParametersAreNonnullByDefault
    package example;


    // file: PublicApi
    package example;

    public class PublicApi {

        /**
         * @param firstname MUST NOT be null
         * @param lastname MUST NOT be null
         */

        public Person createPerson(
                // Spotbugs ignores the param annotations, but IDEs will show problems
                @Nullable String firstname, // Users  might send null
                @Nullable String lastname // Users might send null
                ) {
            if (firstname == null) throw new IllagalArgumentException(...);
            if (lastname == null) throw new IllagalArgumentException(...);
            return doCreatePerson(fistname, lastname, nickname);
        }

        @NonNull // Spotbugs checks that method cannot return null
        private Person doCreatePerson(
                 String firstname, // Spotbugs checks null cannot be passed, because package has ParametersAreNonnullByDefault
                 String lastname,
                 @Nullable String nickname // tell Spotbugs null is ok
                 ) {
             return new Person(firstname, lastname, nickname);
        }

        @CheckForNull // Do not use @Nullable here, Spotbugs will ignore it, though IDEs respect it
        private Person getNickname(
             String firstname,
             String lastname) {
             return NICKNAMES.get(firstname + ':' + lastname);
        }
    }

    请注意,在取消引用可为空的方法参数时(在编写spotbugs时,版本3.1),无法使spotbugs发出警告。也许棋盘架可以做到。


    在等待它被排序的上游(Java 8?)您还可以定义自己的项目本地@NotNull@Nullable注释。在使用JavaSE的情况下,这也是有用的,默认情况下EDCOX1 2不可用。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    import java.lang.annotation.*;

    /**
     * Designates that a field, return value, argument, or variable is
     * guaranteed to be non-null.
     */

    @Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.LOCAL_VARIABLE})
    @Documented
    @Retention(RetentionPolicy.CLASS)
    public @interface NotNull {}

    /**
     * Designates that a field, return value, argument, or variable may be null.
     */

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

    诚然,这在很大程度上是为了装饰或将来的校对目的,因为上面显然没有添加对这些注释的静态分析的任何支持。


    如果您是为Android开发的,那么您与Eclipse有点关联(编辑:在编写时,不再是这样),Eclipse有自己的注释。它包含在Eclipse3.8+中(juno),但默认情况下是禁用的。

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

    选中"启用基于批注的空分析"

    http://wiki.eclipse.org/jdt_-core/null_-analysis用法对设置有建议。但是,如果您的工作区中有外部项目(如Facebook SDK),它们可能不满足这些建议,并且您可能不想在每次更新SDK时修复它们;-)

    我使用:

  • 空指针访问:错误
  • 违反空规格:错误(链接到点1)
  • 潜在的空指针访问:警告(否则facebook sdk将有警告)
  • 空批注和空推理之间的冲突:警告(链接到点3)

  • 如果您正在处理一个大型项目,那么最好创建自己的@Nullable和/或@NotNull注释。

    例如:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    @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
    {
    }

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

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

    • 这是一个内在的东西。(无功能或技术影响)
    • 有许多用法。
    • 类似于ide的intellij支持自定义的@Nullable/@NotNull注释。
    • 大多数框架也喜欢使用自己的内部版本。

    其他问题(见评论):

    如何在Intellij中配置?

    Click the"police officer" in the lower right corner of the IntelliJ status bar. And click"Configure inspections" in the popup. Next ...
    configure annotations


    在Java 8号有另一条路可以做这件事。我正在做两件事来实现我所需要的

  • java.util.Optional写入零场与类型解释
  • 检查所有不可撤销的场地在建筑时间不是零
  • Example:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    import static java.util.Objects.requireNonNull;

    public class Role {

      private final UUID guid;
      private final String domain;
      private final String name;
      private final Optional<String> description;

      public Role(UUID guid, String domain, String name, Optional<String> description) {
        this.guid = requireNonNull(guid);
        this.domain = requireNonNull(domain);
        this.name = requireNonNull(name);
        this.description = requireNonNull(description);
      }

    所以我的问题是,当我们使用爪哇8时,我们是否需要注释?

    编辑:我发现有人认为使用Optional不好的做法,在论据中,有一个很好的讨论,与专业人士和其他人在这里,为什么Java 8的选择不被用于论据


    太阳现在没有自己的了吗?这是什么:http://www.java2s.com/open-source/java-document/6.0-jdk-modules-com.sun/istack/com.sun.istack.internal.htm

    这似乎是包装在过去几年里我使用的所有版本的Java。

    编辑:正如下面的评论中提到的,您可能不想使用这些。在这种情况下,我投票赞成IntellijJetBrains注释!


    如果您使用Spring框架构建应用程序,我建议您使用javax.validation.constraints.NotNullComing,它来自以下依赖项中打包的bean验证:

    1
    2
    3
    4
    5
        <dependency>
            <groupId>javax.validation</groupId>
            validation-api</artifactId>
            <version>1.1.0.Final</version>
        </dependency>

    这个注释的主要优点是Spring同时支持方法参数和用javax.validation.constraints.NotNull注释的类字段。要启用支持,只需执行以下操作:

  • 提供用于beans验证的api jar和带有jsr-303/jsr-349注释验证程序实现的jar(与hibernate validator 5.x依赖项一起提供):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <dependency>
        <groupId>javax.validation</groupId>
        validation-api</artifactId>
        <version>1.1.0.Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        hibernate-validator</artifactId>
        <version>5.4.1.Final</version>
    </dependency>
  • 为Spring上下文提供方法验证后处理器

    1
    2
    3
    4
    5
    6
    7
    8
    9
      @Configuration
      @ValidationConfig
      public class ValidationConfig implements MyService {

            @Bean
            public MethodValidationPostProcessor providePostProcessor() {
                  return new MethodValidationPostProcessor()
            }
      }
  • 最后,使用Spring的org.springframework.validation.annotation.Validated注释类,验证将由Spring自动处理。

  • 例子:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    @Service
    @Validated
    public class MyServiceImpl implements MyService {

      @Override
      public Something doSomething(@NotNull String myParameter) {
            // No need to do something like assert myParameter != null  
      }
    }

    当您尝试调用方法dosomething并将null作为参数值传递时,spring(通过hibernatevalidator)将抛出ConstraintViolationException。这里不需要人工操作。

    您还可以验证返回值。

    javax.validation.constraints.NotNullComing for Beans验证框架的另一个重要好处是,目前它仍在开发中,新版本2.0计划了新功能。

    那么@Nullable呢?beans验证1.1中没有类似的内容。好吧,我可以论证一下,如果你决定使用@NotNull而不是没有用@NonNull注释的所有东西实际上是"可以空的",那么@Nullable注释是无用的。


    关于intellij的一个好处是不需要使用它们的注释。你可以自己写,也可以使用你喜欢的其他工具。你甚至不局限于一种类型。如果您使用的两个库使用不同的@notnull注释,则可以告诉intellij同时使用这两个注释。为此,请转到"配置检查",单击"恒定条件和例外"检查,然后单击"配置检查"按钮。我尽可能地使用空度检查器,所以我设置了Intellij来使用这些注释,但是您可以使用任何其他工具。(我对其他工具没有意见,因为我多年来一直在使用Intellij的检查,我喜欢它们。)


    另一个选择是与Antlr 4一起提供说明。跟踪脉冲请求;434,the artifact containing the EDOCX1 0 x1 x1 x1 x1 x1 x1 \ x1 \\\\\\ x1 \\\\\ x1注释处理器在软件开发过程中提供额外的保证,通过应用注释来传输信息,包括在方法继承的案例中。