@NonNull
或者:我如何學會停止擔憂並愛上 NullPointerException。
@NonNull
已在 lombok v0.11.10 中引入。總覽
您可以在 record component、方法或建構子的參數上使用 @NonNull
。這會使 lombok 為您產生 null 檢查語句。
Lombok 總是將欄位上各種通常名為 @NonNull
的註解視為訊號,以便在 lombok 通過例如 @Data
為您產生整個方法或建構子時產生 null 檢查。然而,在參數或 record component 上使用 lombok 自己的 @lombok.NonNull
會導致在該方法頂端插入 null 檢查。
null 檢查看起來像 if (param == null) throw new NullPointerException("param is marked non-null but is null");
,並且將插入到您方法的頂端。對於建構子,null 檢查將緊接在任何明確的 this()
或 super()
呼叫之後插入。對於 record component,null 檢查將插入到「精簡建構子」(完全沒有引數列表的那個)中,如果您沒有建構子,則會產生該建構子。如果您以長形式(參數與您的 component 完全匹配)寫出 record 建構子,則不會發生任何事情 - 您必須改為註解此長形式建構子的參數。
如果頂端已存在 null 檢查,則不會產生額外的 null 檢查。
使用 Lombok
import lombok.NonNull;
|
原生 Java
import lombok.NonNull;
|
支援的配置鍵
-
lombok.nonNull.exceptionType
= [NullPointerException
|IllegalArgumentException
|JDK
|Guava
|Assertion
] (預設值:NullPointerException
)。 - 當 lombok 產生 null 檢查
if
語句時,預設情況下,將拋出java.lang.NullPointerException
,並帶有 '欄位名稱 標記為 non-null 但為 null' 作為例外訊息。但是,您可以在此配置鍵中使用IllegalArgumentException
,讓 lombok 拋出該例外,並帶有此訊息。通過使用Assertion
,將產生帶有相同訊息的assert
語句。鍵JDK
或Guava
會導致調用這兩個框架的標準 null 檢查方法:java.util.Objects.requireNonNull([field name here], "[field name here] is marked non-null but is null");
或com.google.common.base.Preconditions.checkNotNull([field name here], "[field name here] is marked non-null but is null");
分別。 -
lombok.nonNull.flagUsage
= [warning
|error
] (預設值:未設定) - 如果已配置,Lombok 將標記任何
@NonNull
的使用情況為警告或錯誤。
小字體
Lombok 的已存在 null 檢查的偵測方案包括掃描看起來就像 lombok 自己的 if 語句或 assert 語句。任何作為 if 語句 'then' 部分的 'throws' 語句,無論是否在大括號中,都算數。任何調用名為 requireNonNull
或 checkNotNull
的方法的調用都算數。if 語句的條件必須看起來完全像 PARAMNAME == null
;assert 語句必須看起來完全像 PARAMNAME != null
。對 requireNonNull
樣式方法的調用必須是獨立的(僅調用該方法的語句),或者必須是賦值或變數宣告語句的表達式。您的方法中不是這種 null 檢查的第一個語句會停止檢查 null 檢查的過程。
雖然 @Data
和其他產生方法的 lombok 註解將觸發各種眾所周知的註解,這些註解表示欄位絕不能為 @NonNull
,但此功能僅在 lombok
套件中 lombok 自己的 @NonNull
註解上觸發。
在基本型別參數上使用 @NonNull
會導致警告。不會產生 null 檢查。
在抽象方法的參數上使用 @NonNull
過去會產生警告;從 1.16.8 版本開始,情況已不再如此,以承認 @NonNull
也具有文檔作用的概念。出於同樣的原因,您可以將方法註解為 @NonNull
;這是允許的,不會產生警告,也不會產生任何程式碼。