Spring+Lombok场景下字段已设默认值仍抛出NPE的问题如何解决
问题根因
- 类级别
@NonNull无效:Lombok的@NonNull仅作用于字段、方法参数、方法返回值,标注在类上不会触发任何校验逻辑,属于无效配置。 - 无参构造与
@NonNull字段冲突:同时使用@NoArgsConstructor和字段级@NonNull时,Lombok生成的无参构造不会为returnCde设置初始值,也不会触发空值校验,通过无参构造实例化的对象returnCde默认就是null。 - 直接访问字段绕过兜底逻辑:你自定义的空值返回逻辑仅写在
getReturnCde方法中,如果业务代码、序列化框架(如Jackson)直接访问returnCde字段,不会触发你的兜底逻辑,拿到的就是null,后续操作就会触发NPE。 - getter逻辑存在副作用:你在getter中修改字段值的操作不是线程安全的,多线程场景下可能出现并发问题。
解决方案
核心修复(必做)
给returnCde字段设置默认初始值,从根源避免字段为null,不需要完全依赖getter的兜底逻辑:
@JsonAlias("ax21:returnCde") @NonNull private String returnCde = "01";
此时不管是无参构造实例化,还是反序列化时入参没有对应returnCde字段,字段初始值都是"01",不会再出现空值。
优化配置(可选)
- 移除无效的类级别
@NonNull注解,避免配置歧义。 - 若无参构造仅用于Jackson反序列化,可将其访问权限设为私有,禁止外部随意调用:
@NoArgsConstructor(access = AccessLevel.PRIVATE)
- 简化getter逻辑,避免修改原字段产生副作用:
public String getReturnCde() { return returnCde == null ? "01" : returnCde; }
如果已经设置了字段默认值,也可以直接删除自定义getter,不再需要额外的空值判断。
4. 如果要避免反序列化时被显式传入空值覆盖默认值,可以添加Jackson注解配置空值处理逻辑:
@JsonSetter(nulls = Nulls.SKIP) @NonNull private String returnCde = "01";
配置后反序列化时如果入参returnCde为null,会自动跳过赋值,保留默认值"01"。
内容的提问来源于stack exchange,提问作者iamjoshua
相关产品推荐
相关产品推荐

