lombok 的 @nonnull 注解在编译期生成 objects.requirenonnull 调用,该方法内部抛出 nullpointerexception;它作用于构造函数参数、setter 参数等位置,不直接使用 throw 关键字。

Lombok 的 @NonNull 注解本身不会直接使用 throw 关键字抛出异常,而是由 Lombok 在编译期自动生成非空校验代码(调用 Objects.requireNonNull),该方法内部会抛出 NullPointerException —— 这就是你看到的“抛出 NPE”的实际来源。
理解 @NonNull 的生成逻辑
Lombok 并不手动写 throw new NullPointerException(...),而是插入标准的空值检查语句。例如:
你写:
@RequiredArgsConstructor
public class User {
private final @NonNull String name;
}
Lombok 编译后等效生成:
public User(String name) {
this.name = java.util.Objects.requireNonNull(name, "name is marked non-null but is null");
}
而 Objects.requireNonNull 的实现中就包含 throw new NullPointerException()。
@NonNull 作用的位置
该注解生效于以下位置,Lombok 会为对应参数/字段生成校验:
- 构造函数参数(配合
@RequiredArgsConstructor、@AllArgsConstructor) - Setter 方法参数(配合
@Setter) - 普通方法参数(需配合
@NonNul的 Lombok 插件支持,但默认不处理方法参数,除非启用 experimental 特性或使用@lombok.NonNull+ 手动配置)
自定义抛出异常行为(不推荐但可行)
如果你希望替换默认的 NullPointerException(比如抛出自定义异常),Lombok 本身不提供开关。此时需放弃 @NonNull,改用手动校验:
public User(String name) {
if (name == null) {
throw new IllegalArgumentException("name must not be null");
}
this.name = name;
}
注意:这样就绕过了 Lombok 的自动校验,也失去了 @NonNull 带来的简洁性和一致性。
调试与定位 NPE 来源
当遇到 NPE 时,堆栈跟踪通常指向 Objects.requireNonNull 调用处(如第 X 行构造函数)。这是正常现象,说明校验已生效。你可以:
- 检查传入构造函数或 setter 的值是否为
null - 确认 Lombok 编译插件已正确安装(IDE 需启用 annotation processing)
- 避免在字段上误用
@NonNull而未配合适当构造器(否则无校验生成)
本质上,throw 是 Objects.requireNonNull 内部完成的,你无需、也不应直接在 Lombok 注解中写 throw;它通过约定和编译期增强实现了安全、透明的空值防护。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











