【问题标题】:Why would I use Lombok-Annotation @NonNull?为什么我要使用 Lombok-Annotation @NonNull?
【发布时间】:2019-11-06 04:13:11
【问题描述】:

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。

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

【问题讨论】:

  • 考虑一个例子。您正在设计 api,字段标记为@NonNull。当 corresponding json 命中后端 api 时,它会在控制器级别抛出 NPE 而不是通过代码,这也称为fail-fast 和其他事情取决于使用案例
  • 我认为该示例旨在显示如果您对 @NonNull 注释进行编码(因此是 Vanilla Java 标题),则生成的代码.
  • @Jos,这可能是一个正确的猜测。这确实可以解释为什么在某些文档页面(12)中,他们在 valinna Java 中去除了 Lombok 注释,而在其他页面(NonNull)中,他们保留了它们——也许代码正是以这种方式生成的(剥离注释并保留在这里)。那么唯一的问题是为什么他们以如此不同的方式生成代码。
  • 看来你是对的。我以为他们是一样的
  • @Sasha lombok 总是剥离它们,@NonNull 除外。原因是:nonnull 是唯一用于文档/lint-tool 目的的。所有其他 lombok 注释都没有,因此可以在 lombok 完成后删除。

标签: java annotations lombok


【解决方案1】:

注解的想法是避免代码中出现if (person == null),并保持代码更简洁。

【讨论】:

  • 如果检查未添加到代码中,NPE 会以任何一种方式抛出。
  • 是的。如果你在这里解决person.xxxx。但是你可以将它传递给一个函数并在下一行得到它。使用注释,您可以检查是否在开头并使用干净的代码。
  • @RoeeGavirel,在执行任何 person.xxx 或将 person 传递给函数之前执行了 if (person == null) throw new NullPointerException("person is marked @NonNull but is null")
  • @Sashe - 是的,但是拥有@NonNull 会使if (person == null) 变得多余。
  • @RoeeGavirel,是的,没错——这就是米特斯的问题所在(如果我们保留if (person == null),为什么还要添加@NonNull)。
【解决方案2】:

恕我直言,你理解错了that documentation page

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

它只是说像这样的代码(我们称之为代码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 是“vanilla Java”代码。预计不会第二次被龙目岛处理。所以 代码 B 中的@NonNull 只是一个简单的注释,对行为没有影响(至少,不是龙目岛的意思)。

Lombok 为何以这种方式工作是另一个问题——为什么它不从生成的代码中删除 @NonNull。最初我什至thought 认为它可能是该文档页面中的一个错误。但是,正如 Lombok 作者在 his comment 中所解释的那样,@NonNulls 被故意保留用于文档和其他工具可能进行的处理。

【讨论】:

  • 虽然你说的没有错,但仍然可以使用 lombok 注释没有它们的注释处理器。同样可能的是,他们的示例仍然选择将参数注释为 @NonNull 纯粹是出于文档目的。
  • @user2478398,他们不会在other documentation pages中这样做。
  • Lombok 作者在这里:不,这不是假的。 'post lombok' 示例仍然具有 nonnull 注释的原因是,与大多数其他 lombok 注释不同,如果您 delombok 这段代码,我们会将注释留在其中。这是因为,正如@mernst 所说,@NonNull 注释还提供文档和“用于 linter 的输入”目的,这是大多数其他 lombok 注释所不具备的。该示例显示 lombok 将生成一个 nullcheck,仅此而已。
【解决方案3】:

它的用途与

相似

java.util.Objects requireNonNull()

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

【讨论】:

    【解决方案4】:

    编写诸如@NonNull 之类的类型注释有多种用途。

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

    【讨论】:

    • 如果可以告诉 lombok 默认情况下一切都是NonNull 并且只注释可空参数而不是反之亦然...
    【解决方案5】:

    我喜欢龙目岛,但在这种情况下(个人)我更喜欢使用 javax.annotation 中的 @Nonnull 注释和 java.util.Objects 中的 Objects.requireNonNull >。

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

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

    此方法引发 NullPointerException(没有证据)并且令人上瘾 我的 IDE 未报告在方法调用中传递 null 参数(IntelliJ Ultimate 2020.1 EAP - 最新版本 - 带有 lombok 插件)


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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-10
      • 2019-06-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-03
      • 2018-01-13
      • 1970-01-01
      相关资源
      最近更新 更多