为什么要使用Lombok注释@NonNull?

时间:2019-06-24 10:58:40

标签: java annotations lombok

Lombok提供了annotation @NonNull,它会执行nullcheck并抛出NPE(如果配置不同)。

我不明白为什么要使用该文档的example中所述的注释:

private String name;
public NonNullExample(@NonNull Person person) {
    super("Hello");
    if (person == null) {
      throw new NullPointerException("person is marked @NonNull but is null");
    }
    this.name = person.getName();
  }

无论如何都会抛出NPE。使用注释imo的唯一原因是,如果您希望异常不同于NPE。

编辑:我确实知道异常将被显式抛出并因此被“控制”,但是至少错误消息的文本应该是可编辑的,不是吗?

5 个答案:

答案 0 :(得分:1)

恕我直言,您误解了that documentation page

该文档页面并不暗示建议您同时使用Lombok @NonNull批注和类似if (smth == null) throw …的显式检查(以相同的方法) )。

它只是说像这样的代码(我们称其为 code A ):

import lombok.NonNull;

public class NonNullExample extends Something {
  private String name;

  public NonNullExample(@NonNull Person person) {
    super("Hello");
    this.name = person.getName();
  }
}

Lombok会自动(内部)将其翻译成与引用问题的代码相同的代码(我们称其为代码B )。

但是该文档页面并没有说您显式地编写代码B (尽管您被允许;在这种情况下Lombok甚至会尝试防止再次检查)对您来说是没有道理的。它只是说,使用Lombok 您现在可以编写代码A (以及其工作方式 -它会隐式转换为代码B )。

请注意,代码B 是“香草Java”代码。龙目岛预计不会第二次对其进行处理。因此,代码B 中的@NonNull只是一个简单的注释,它对行为没有任何影响(至少不是通过Lombok的方式)。

这是一个单独的问题,为什么Lombok会以这种方式工作-为什么它不会从生成的代码中删除@NonNull。最初,我什至thought都可能是该文档页面中的错误。但是,正如龙目岛(Lombok)作者在his comment中解释的那样,@NonNull被故意保留,目的是用于文档记录和其他工具可能的处理。

答案 1 :(得分:1)

编写类型注解(例如@NonNull)有几个目的。

  • 这是文档:它比Javadoc文本更简洁,更精确地将方法的合同传达给客户。
  • 它启用运行时检查-也就是说,如果有错误的客户端滥用了您的方法,它可以确保程序崩溃并显示有用的错误消息(而不是做更糟的事情)。龙目岛(Lombok)为您做到了这一点,而无需强迫程序员编写运行时检查。 referenced example显示了执行此操作的两种方法:使用单个@NonNull批注或使用显式的程序员编写的检查。 “ Vanilla Java”版本要么有错字(流浪@NonNull),要么在Lombok处理后显示了代码。
  • 它启用编译时检查Checker Framework之类的工具可以保证代码在运行时不会崩溃。诸如NullAwayError ProneFindBugs之类的工具是启发式错误发现程序,它们会警告您某些错误使用null的情况,但并不能给您保证。

答案 2 :(得分:1)

我喜欢龙目岛,但在这种情况下(个人而言),我更喜欢将 javax.annotation 中的@Nonnull注释与 java.util中的Objects.requireNonNull一起使用。对象

以这种方式使用lombok可使代码更整洁,但更加不清晰和易读:

public Builder platform(@NonNull String platform) {
    this.platform = platform;
    return this;
}  

此方法引发NullPointerException(无证据)并成瘾 我的IDE不报告在方法调用中传递空参数的情况(IntelliJ Ultimate 2020.1 EAP-最新版本-带有lombok插件)


因此,我更喜欢以这种方式使用 javax.annotation 中的@Nonnull注释:

public Builder platform(@Nonnull String platform) {
    this.platform = Objects.requireNonNull(platform);
    return this;
}

代码有点冗长,但更清晰,如果我在方法调用中传递null参数,我的IDE能够警告我!

答案 3 :(得分:0)

注释的目的是避免在代码中使用if (person == null),并使代码更整洁。

答案 4 :(得分:0)

它的作用与

相似

java.util.Objects requireNonNull()

或Guava的前提条件。这只是使代码更加紧凑和快速失败。

相关问题