Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/306.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我应该使用哪个@NotNull Java注释?_Java_Nullpointerexception_Null_Annotations_Ide - Fatal编程技术网

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

我应该使用哪个@NotNull Java注释?,java,nullpointerexception,null,annotations,ide,Java,Nullpointerexception,Null,Annotations,Ide,我希望使我的代码更具可读性,并使用IDE代码检查和/或静态代码分析(FindBugs和Sonar)等工具来避免NullPointerException。许多工具似乎彼此不兼容,@NotNull/@NonNull/@NonNull注释并在我的代码中列出所有这些工具,阅读起来会很糟糕。哪一个是“最好的”有什么建议吗?以下是我找到的等效注释列表: javax.validation.constraints.NotNull 为运行时验证而不是静态分析而创建。 edu.umd.cs.findbugs.

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

  • javax.validation.constraints.NotNull

    为运行时验证而不是静态分析而创建。

  • edu.umd.cs.findbugs.annotations.NonNull

    用于()及其后续静态分析,因此用于声纳(现在)
    ,


  • javax.annotation.Nonnull

    这可能也适用于FindBugs,但处于非活动状态。(另见:)

  • org.jetbrains.annotations.NotNull

    IntelliJ IDEA用于静态分析。

  • lombok.NonNull

    用于控制中的代码生成。
    占位符注释,因为没有标准。
    ,

  • android.support.annotation.NonNull

    Android中提供的标记注释,由support annotations package提供

  • org.eclipse.jdt.annotation.NonNull

    Eclipse用于静态代码分析


我使用IntelliJ one,因为我最关心的是IntelliJ标记可能产生NPE的东西。我同意在JDK中没有标准注释是令人沮丧的。有人说要添加它,它可能会被添加到Java7中。在这种情况下,将有一个更多的选择

根据JSR-308,类型注释被推迟到Java8。甚至没有提到JSR-305注释

在最新的JSR-308草案中,有一些关于JSR-305状态的信息。这包括观察到JSR-305注释似乎被放弃。JSR-305页面也显示为“非活动”

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


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

然而,如果JSR-308看起来真的像是要进入Java8,那么如果对JSR-305的兴趣恢复的话,我也不会感到惊讶。好了,JSR-305团队还没有正式放弃他们的工作。他们已经安静了2年多了


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

sun现在不是有自己的吗?这是什么:

这似乎与我在过去几年中使用的所有Java版本一起打包

编辑:如下面的评论所述,您可能不想使用这些。在这种情况下,我投票支持IntelliJ jetbrains

我非常喜欢,它是类型注释()的一个实现,用于实现缺陷检查器,如空值检查器。我还没有真正尝试过任何其他方法来提供任何比较,但是我对这个实现很满意

package lombok;
@Retention(CLASS)
@Target({FIELD, METHOD, PARAMETER, LOCAL_VARIABLE})
public @interface NonNull {}
我不是提供软件的团体的成员,但我是一个粉丝

我喜欢这个系统的四个方面:

  • 它有(@Nullable)的缺陷检查器,但也有and(和其他)的缺陷检查器。我使用第一个(空值),我正在尝试使用第二个(不变性/IGJ)。我正在尝试第三种,但我还不确定是否能长期使用。我还不相信其他检查器的通用性,但很高兴知道框架本身是一个实现各种附加注释和检查器的系统

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

    NNEL默认值导致代码中显式注释的数量最少

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

  • 此框架允许您通过在注释中包含注释来使用:例如
    /*@Nullable*/
    。这很好,因为您可以注释和检查库或共享代码,但仍然能够在不使用框架的另一个项目中使用该库/共享代码。这是一个很好的特性。我已经习惯于使用它,尽管我现在倾向于在我所有的项目上启用Checker框架

  • 该框架有一种方法供您使用,而这种方法还没有通过使用存根文件为空进行注释


  • 在等待上游(Java8?)对此进行分类时,您还可以定义自己的项目本地
    @NotNull
    @Nullable
    注释。这在使用JavaSE时也很有用,默认情况下,
    javax.validation.constraints

    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 {}
    

    不可否认,这主要是为了装饰或未来验证的目的,因为上述内容本身显然没有为这些注释的静态分析添加任何支持。

    只是指出Java验证API(
    javax.Validation.constraints.*
    )没有提供
    @Nullable
    注释,这在静态分析环境中非常有价值。这对于运行时bean验证是有意义的,因为这是Java中任何非原语字段的默认值(即
    org.eclipse.jdt.annotation.NonNull
    
    @NotNullByDefault
    package com.example.foo;
    
    <dependency>
        <groupId>org.jetbrains</groupId>
        <artifactId>annotations</artifactId>
        <version>15.0</version>
    </dependency> 
    
    compile 'com.android.support:support-annotations:23.1.1'
    
    import android.support.annotation.NonNull;
    
    void foobar(@NonNull Foo bar) {}
    
        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);
          }
    
      //Non null description
      public Role(UUID guid, String domain, String name, String description) {
            this.guid = requireNonNull(guid);
            this.domain = requireNonNull(domain);
            this.name = requireNonNull(name);
    
            // description will never be null
            requireNonNull(description);
    
            // but wrapped with an Optional
            this.description = Optional.of(description);
          }
    
      // Null description is assigned to Optional.empty
      public Role(UUID guid, String domain, String name) {
            this.guid = requireNonNull(guid);
            this.domain = requireNonNull(domain);
            this.name = requireNonNull(name);
            this.description = Optional.empty();
          }
    
    // file: package-info.java
    @javax.annotation.ParametersAreNonnullByDefault
    package example;
    
    
    // file: PublicApi
    package example;
    
    public interface PublicApi {
    
        Person createPerson(
            // NonNull by default due to package-info.java above
            String firstname,
            String lastname);
    }
    
    // file: PublicApiImpl
    public class PublicApiImpl implements PublicApi {
        public Person createPerson(
                // In Impl, handle cases where library users still pass null
                @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);
        }
    }
    
            public Person createPerson(
                    @NonNull String firstname,
                    @NonNull String lastname
                    ) {
                // even though parameters annotated as NonNull, library clients might call with null.
                if (firstname == null) throw new IllagalArgumentException(...);
                if (lastname == null) throw new IllagalArgumentException(...);
                return doCreatePerson(fistname, lastname, nickname);
            }
    
    @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 
    {
    }
    
    public @interface NonNull {}
    
    public @interface Nullable {}
    
    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
    package android.support.annotation;
    @Retention(CLASS)
    @Target({FIELD, METHOD, PARAMETER})
    public @interface NonNull {}
    
    package edu.umd.cs.findbugs.annotations;
    @Retention(CLASS)
    @Target({FIELD, METHOD, PARAMETER, LOCAL_VARIABLE})
    public @interface NonNull {}
    
    package org.eclipse.jdt.annotation;
    @Retention(CLASS)
    @Target({ TYPE_USE })
    public @interface NonNull {}
    
    package org.jetbrains.annotations;
    @Retention(CLASS)
    @Target({FIELD, METHOD, PARAMETER, LOCAL_VARIABLE})
    public @interface NotNull {String value() default "";}
    
    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;
            }
        }
    }
    
    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 {}
    
    package android.support.annotation;
    @Retention(CLASS)
    @Target({METHOD, PARAMETER, FIELD})
    public @interface Nullable {}
    
    package edu.umd.cs.findbugs.annotations;
    @Target({FIELD, METHOD, PARAMETER, LOCAL_VARIABLE})
    @Retention(CLASS)
    public @interface Nullable {}
    
    package org.eclipse.jdt.annotation;
    @Retention(CLASS)
    @Target({ TYPE_USE })
    public @interface Nullable {}
    
    package org.jetbrains.annotations;
    @Retention(CLASS)
    @Target({FIELD, METHOD, PARAMETER, LOCAL_VARIABLE})
    public @interface Nullable {String value() default "";}
    
    package javax.annotation;
    @TypeQualifierNickname
    @Nonnull(when = When.UNKNOWN)
    @Retention(RUNTIME)
    public @interface Nullable {}
    
    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 {}
    
    package lombok;
    @Retention(CLASS)
    @Target({FIELD, METHOD, PARAMETER, LOCAL_VARIABLE})
    public @interface NonNull {}
    
    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();
        }
    }
    
        <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
            <version>1.1.0.Final</version>
        </dependency>
    
    <dependency>
        <groupId>javax.validation</groupId>
        <artifactId>validation-api</artifactId>
        <version>1.1.0.Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-validator</artifactId>
        <version>5.4.1.Final</version>
    </dependency>
    
      @Configuration
      @ValidationConfig
      public class ValidationConfig implements MyService {
    
            @Bean
            public MethodValidationPostProcessor providePostProcessor() {
                  return new MethodValidationPostProcessor()
            }
      }
    
    @Service
    @Validated
    public class MyServiceImpl implements MyService {
    
      @Override
      public Something doSomething(@NotNull String myParameter) {
            // No need to do something like assert myParameter != null  
      }
    }
    
    <dependency>
        <groupId>org.jetbrains</groupId>
        <artifactId>annotations-java5</artifactId>
        <version>15.0</version>
    </dependency>
    
    implementation 'org.jetbrains:annotations-java5:15.0'
    
    @org.springframework.lang.NonNullApi
    package com.acme;