Which @NotNull Java annotation should I use?

前端 未结 22 2807
梦如初夏
梦如初夏 2020-11-22 02:44

I\'m looking to make my code more readable as well as use tooling like IDE code inspection and/or static code analysis (FindBugs and Sonar) to avoid NullPointerExceptions.

相关标签:
22条回答
  • 2020-11-22 03:34

    There are already too many answers here, but (a) it's 2019, and there's still no "standard" Nullable and (b) no other answer references Kotlin.

    The reference to Kotlin is important, because Kotlin is 100% interoperable with Java and it has a core Null Safety feature. When calling Java libraries, it can take advantage of those annotations to let Kotlin tools know if a Java API can accept or return null.

    As far as I know, the only Nullable packages compatible with Kotlin are org.jetbrains.annotations and android.support.annotation (now androidx.annotation). The latter is only compatible with Android so it can't be used in non-Android JVM/Java/Kotlin projects. However, the JetBrains package works everywhere.

    So if you develop Java packages that should also work in Android and Kotlin (and be supported by Android Studio and IntelliJ), your best choice is probably the JetBrains package.

    Maven:

    <dependency>
        <groupId>org.jetbrains</groupId>
        <artifactId>annotations-java5</artifactId>
        <version>15.0</version>
    </dependency>
    

    Gradle:

    implementation 'org.jetbrains:annotations-java5:15.0'
    
    0 讨论(0)
  • 2020-11-22 03:36

    If you are building your application using Spring Framework I would suggest using javax.validation.constraints.NotNull comming from Beans Validation packaged in following dependency:

        <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
            <version>1.1.0.Final</version>
        </dependency>
    

    The main advantage of this annotation is that Spring provides support for both method parameters and class fields annotated with javax.validation.constraints.NotNull. All you need to do to enable support is:

    1. supply the api jar for beans validation and jar with implementation of validator of jsr-303/jsr-349 annotations (which comes with Hibernate Validator 5.x 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>
      
    2. provide MethodValidationPostProcessor to spring's context

        @Configuration
        @ValidationConfig
        public class ValidationConfig implements MyService {
      
              @Bean
              public MethodValidationPostProcessor providePostProcessor() {
                    return new MethodValidationPostProcessor()
              }
        }
      
    3. finally you annotate your classes with Spring's org.springframework.validation.annotation.Validated and validation will be automatically handled by Spring.

    Example:

    @Service
    @Validated
    public class MyServiceImpl implements MyService {
    
      @Override
      public Something doSomething(@NotNull String myParameter) {
            // No need to do something like assert myParameter != null  
      }
    }
    

    When you try calling method doSomething and pass null as the parameter value, spring (by means of HibernateValidator) will throw ConstraintViolationException. No need for manuall work here.

    You can also validate return values.

    Another important benefit of javax.validation.constraints.NotNull comming for Beans Validation Framework is that at the moment it is still developed and new features are planned for new version 2.0.

    What about @Nullable? There is nothing like that in Beans Validation 1.1. Well, I could arguee that if you decide to use @NotNull than everything which is NOT annotated with @NonNull is effectively "nullable", so the @Nullable annotation is useless.

    0 讨论(0)
  • 2020-11-22 03:37

    For Android projects you should use android.support.annotation.NonNull and android.support.annotation.Nullable. These and other helpful Android-specific annotations are available in the Support Library.

    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.

    0 讨论(0)
  • 2020-11-22 03:37

    While waiting for this to be sorted out upstream (Java 8?), you could also just define your own project-local @NotNull and @Nullable annotations. This can be useful also in case you're working with Java SE, where javax.validation.constraints isn't available by default.

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

    This would admittedly largely be for decorative or future-proofing purposes, since the above obviously doesn't in and of itself add any support for the static analysis of these annotations.

    0 讨论(0)
  • 2020-11-22 03:37

    Spring 5 has @NonNullApi at the package level. This seems like a convenient choice for a project that already has Spring dependencies. All fields, parameters and return values default to @NonNull and @Nullable can be applied in the few places that differ.

    File package-info.java:

    @org.springframework.lang.NonNullApi
    package com.acme;
    

    https://docs.spring.io/spring-data/commons/docs/current/reference/html/#repositories.nullability.annotations

    0 讨论(0)
  • 2020-11-22 03:39

    If anyone is just looking for the IntelliJ classes: you can get them from the maven repository with

    <dependency>
        <groupId>org.jetbrains</groupId>
        <artifactId>annotations</artifactId>
        <version>15.0</version>
    </dependency> 
    
    0 讨论(0)
提交回复
热议问题