@NonNull
或者:我如何学会停止担忧并爱上 NullPointerException。
@NonNull
在 lombok v0.11.10 中引入。概述
您可以在记录组件、方法或构造函数的参数上使用 @NonNull
。 这将使 Lombok 为您生成空值检查语句。
Lombok 始终将字段上各种通常名为 @NonNull
的注解视为信号,以便在 Lombok 通过例如 @Data
为您生成整个方法或构造函数时生成空值检查。 但是,在参数或记录组件上使用 Lombok 自己的 @lombok.NonNull
会导致在该方法的顶部插入空值检查。
空值检查看起来像 if (param == null) throw new NullPointerException("param is marked non-null but is null");
,并将插入到您方法的顶部。 对于构造函数,空值检查将紧跟在任何显式的 this()
或 super()
调用之后插入。 对于记录组件,空值检查将插入到“紧凑构造函数”(根本没有参数列表的构造函数)中,如果您没有构造函数,则会生成该构造函数。 如果您以长格式(参数与您的组件完全匹配)写出了记录构造函数,则不会发生任何事情 - 您必须改为注解此长格式构造函数的参数。
如果在顶部已经存在空值检查,则不会生成额外的空值检查。
使用 Lombok
import lombok.NonNull;
|
原生 Java
import lombok.NonNull;
|
支持的配置键
-
lombok.nonNull.exceptionType
= [NullPointerException
|IllegalArgumentException
|JDK
|Guava
|Assertion
] (默认值:NullPointerException
)。 - 当 lombok 生成空值检查
if
语句时,默认情况下,将抛出java.lang.NullPointerException
,异常消息为“字段名称被标记为非空,但实际上为空”。 但是,您可以在此配置键中使用IllegalArgumentException
,以便 Lombok 抛出该异常,并使用相同的消息。 通过使用Assertion
,将生成具有相同消息的assert
语句。 键JDK
或Guava
会分别调用这两个框架的标准空值检查方法:java.util.Objects.requireNonNull([字段名称在此处], "[字段名称在此处] 被标记为非空,但实际上为空");
或com.google.common.base.Preconditions.checkNotNull([字段名称在此处], "[字段名称在此处] 被标记为非空,但实际上为空");
。 -
lombok.nonNull.flagUsage
= [warning
|error
] (默认值:未设置) - 如果配置了,Lombok 将把任何
@NonNull
的使用标记为警告或错误。
小字细则
Lombok 用于检测已存在的空值检查的方案包括扫描看起来与 Lombok 自身类似的 if 语句或 assert 语句。 if 语句“then”部分中的任何“throws”语句,无论是否在大括号中,都算数。 对任何名为 requireNonNull
或 checkNotNull
的方法的任何调用都算数。 if 语句的条件必须看起来完全像 PARAMNAME == null
; assert 语句必须看起来完全像 PARAMNAME != null
。 对 requireNonNull
样式方法的调用必须是独立的(仅调用该方法的语句),或者必须是赋值或变量声明语句的表达式。 方法中不是此类空值检查的第一个语句会停止检查空值检查的过程。
虽然 @Data
和其他生成方法的 Lombok 注解会触发各种众所周知的注解,这些注解表明该字段绝不能为 @NonNull
,但此功能仅在 Lombok 包中 Lombok 自己的 @NonNull
注解上触发。
在原始类型参数上使用 @NonNull
会导致警告。 不会生成空值检查。
在抽象方法的参数上使用 @NonNull
过去会生成警告; 从 1.16.8 版本开始,情况已不再如此,以承认 @NonNull
也具有文档作用的概念。 出于同样的原因,您可以将方法注解为 @NonNull
; 这是允许的,不会生成警告,也不会生成任何代码。