簡體   English   中英

為什么我要使用 Lombok-Annotation @NonNull?

[英]Why would I use Lombok-Annotation @NonNull?

Lombok 提供了@NonNull注釋,它執行空檢查並拋出一個 NPE(如果沒有以不同的方式配置)。

我不明白為什么我會使用該文檔示例中所述的注釋:

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 不同。

編輯:我知道異常會被顯式拋出並因此被“控制”,但至少錯誤消息的文本應該是可編輯的,不是嗎?

編寫諸如@NonNull類的類型注釋有多種用途。

  • 它是文檔:它以比 Javadoc 文本更簡潔和精確的方式將方法的契約傳達給客戶端。
  • 它啟用運行時檢查——也就是說,如果有錯誤的客戶端誤用你的方法,它可以保證你的程序崩潰並顯示有用的錯誤消息(而不是做更糟糕的事情)。 Lombok 會為您執行此操作,而無需強制程序員編寫運行時檢查。 引用的示例顯示了執行此操作的兩種方法:使用單個@NonNull注釋或使用顯式程序員編寫的檢查。 “Vanilla Java”版本要么有拼寫錯誤(錯誤的@NonNull ),要么在 Lombok 處理后顯示代碼。
  • 它啟用編譯時檢查 Checker Framework等工具可以保證代碼在運行時不會崩潰。 諸如NullAwayError ProneFindBugs 之類的工具是啟發式錯誤查找器,它們會警告您有關 null 的一些誤用,但不給您保證。

恕我直言,您已經錯誤地理解了該文檔頁面

該文檔頁面並不意味着建議您同時使用 Lombok @NonNull注釋和顯式if (smth == null) throw … -like 檢查(以相同的方法)。

它只是說這樣的代碼(我們稱之為代碼 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 最初我什至認為這可能是該文檔頁面中的錯誤。 但是,正如 Lombok 作者在他的評論中解釋的那樣, @NonNull是有意保留的,目的是記錄和其他工具可能進行的處理。

我喜歡 lombok 但在這種情況下(個人)我更喜歡使用javax.annotation 中@Nonnull注釋和java.util.Objects 中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;
}

代碼有點冗長但更清晰,如果我在方法調用時傳遞空參數,我的 IDE 能夠警告我!

注釋的想法是避免代碼中的if (person == null)並保持代碼清潔。

它用於類似的目的

java.util.Objects requireNonNull()

或番石榴的先決條件。 這只會使代碼更加緊湊和快速失敗。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM