我希望使我的代码更具可读性,以及使用工具,如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


当前回答

如果你正在使用Spring框架构建应用程序,我建议使用来自bean Validation的javax.validation.constraints.NotNull,它被打包在以下依赖项中:

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

这种注释的主要优点是Spring同时支持用javax.validation.constraints.NotNull注释的方法参数和类字段。要启用支持,您需要做的是:

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> provide MethodValidationPostProcessor to spring's context @Configuration @ValidationConfig public class ValidationConfig implements MyService { @Bean public MethodValidationPostProcessor providePostProcessor() { return new MethodValidationPostProcessor() } } finally you annotate your classes with Spring's org.springframework.validation.annotation.Validated and validation will be automatically handled by Spring.

例子:

@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.NotNull对Beans验证框架的另一个重要好处是,目前它仍在开发中,新特性计划在新版本2.0中实现。

@Nullable呢?在Beans Validation 1.1中没有类似的东西。好吧,我可以争辩说,如果你决定使用@ nonull,而不是任何没有用@NonNull注释的东西都是有效的“nullable”,所以@Nullable注释是无用的。

其他回答

Spring 5在包级别上有@NonNullApi。对于已经具有Spring依赖项的项目来说,这似乎是一个方便的选择。所有字段、参数和返回值默认为@NonNull和@Nullable,可以应用在少数不同的地方。

文件package-info.java:

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

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

Eclipse也有自己的注释。

org.eclipse.jdt.annotation.NonNull

详情见http://wiki.eclipse.org/JDT_Core/Null_Analysis。

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

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

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

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

我使用:

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

Another option is the annotations provided with ANTLR 4. Following Pull Request #434, the artifact containing the @NotNull and @Nullable annotations includes an annotation processor that produces compile-time errors and/or warnings in the event one of these attributes is misused (for example, if both are applied to the same item, or if @Nullable is applied to item with a primitive type). The annotation processor provides additional assurance during the software development process that the information conveyed by the application of these annotations is accurate, including in cases of method inheritance.

只是指出Java验证API (javax.validation.constraints.*)没有提供@Nullable注释,这在静态分析上下文中非常有价值。这对于运行时bean验证是有意义的,因为这是Java中任何非基本字段的默认值(即没有需要验证/强制的内容)。为达到上述目的,应权衡备选方案。