详解Lombok的坑 Lombok使用中需注意的问题
详解Lombok的坑
今日IT小知识分享:详解Lombok的坑的相关介绍,接下来一起来看看吧。
不念最近踩了一个lombok的坑,有点意思,给你分享一波。
之前写过一个公共的服务接口,这个接口已经有好几个系统对接并稳定运行了很长一段时间了,长到这个接口都已经交接给别的同事一年多了。
因为是基础服务嘛,相对稳定,所以交出去之后他也一直没有动过这部分代码。
但是有一天有新服务要对接这个接口,同事反馈说遇到一个诡异的问题,这个新服务调用的时候,接口里面报了一个空指针异常。
根据日志来看,那一行代码大概是这样的:
//为了脱敏我用field1、2、3来代替了
if(reqDto.getField1()
&& reqDto.getField2()!=null
&& reqDto.getField3()!=null){
//满足条件则执行对应业务逻辑
}
reqDto 是接口入参对象,有好多字段。具体到 field1、2、3 大概是这样的:
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ReqDto {
private Boolean field1 = true;
private String field2;
private String field3;
}
所以看到这一行抛出了空指针异常,我直接就给出了一个结论:首先排除 field1 为 null,因为有默认值。那只可能 reqDto 传进来的就是 null,导致在 get 字段的时候出现了空指针异常。
但是很不幸,这个结论一秒就被推翻了。
因为 reqDto 是请求入参,在方法入口处选了几个关键字段进行打印。
如果 reqDto 是 null 的话,那么日志打印的时候就会先抛出空指针异常了。
然后我又开始怀疑是部署的代码版本和我们看的版本不一致,可能并不是这一行报错。
和测试同学确认之后,也排除了这个方向。
盯着报错的那一行代码又看了几秒,排除所有不可能之后,我又下了一个结论:调用的时候,传递进来的 field1 主动设值为了 null。
也就是说调用方有这样的代码:
ReqDto reqDto = new ReqDto();
reqDto.setField1(null);
我知道,这样的代码看起来很傻,但是确实只剩下这一种可能了。
于是我去看了调用方构建参数的写法,准备吐槽一波为什么要写设置为 null 这样的坑爹代码。
然而,当时我就被打脸了,调用方的代码是这样的:
ReqDto reqDto = ReqDto.builder()
.field2("why")
.field3("max")
.build();
用的是 builder 模式构建的对象,并不是直接 new 出来的对象。
我一眼看着这个代码也没有发现毛病,虽然没有对 Boolean 类型的 field1 进行设值,但是我有默认值啊。
问调用方为什么不设值,对方的回答也是一句话:我看你有默认值,我本来也是想传 true,但是一看你的默认值就是 true,所以就没有给值了。
对啊,这逻辑无懈可击啊,难道……
是 builder 在里面搞事情了?
于是我里面写了一个代码进行了验证:

好你个浓眉大眼的 @Builder,果然是你在搞事情。
问题现象基本上就算是定位到了,用 @Builder 注解的时候,丢失默认值了。
所以拿着 “@Builder 默认值” 这样的关键词一搜:

立马就能找到这样的一个注解:@Builder.Default
对应到我的案例应该是这样的:
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ReqDto {
@Builder.Default
private Boolean field1 = true;
private String field2;
private String field3;
}
这样,再次运行 Demo 就会发现有默认值了:

同时我们从两个写法生成的 class 文件中也可以看出一些端倪。
没有@Builder.Default 注解的时候,class 文件中 ReqDtoBuilder 类中关于 field1 字段是这样的:
相关阅读
-
DNS服务器未响应怎么解决? DNS未响应最简单的修复办法
今天小编介绍DNS服务器未响应怎么解决的电脑方面的小经验,接下来IT袋网带大家一起了解。 DNS服务器未响应是一种常见的网络问题,可能导致无法访问网站或网络服务。 DNS(域名系统)负责
-
Nacos核心功能点有哪些 "Nacos的关键功能有哪些?"
本文为您带来的是Nacos核心功能点有哪些的内容,接下来小编为网友介绍。 服务注册: Nacos Client会通过发送REST请求的方式向Nacos Server注册自己的服务,提供自身的元数据,比如ip地址、端口等
-
Kafka为什么这么快? 为何卡夫卡如此迅猛?
如果想了解Kafka为什么这么快方面的知识,具体详情如下: 深入地从 IO、线程、数据结构、编码等方面剖析了Redis “快”的内部秘密。 下面不念讲一讲Kafka性能优化方面的知识,不念决定将这
-
怎么注册自己的网站域名账号 申请域名网址的流程
一篇很详细的教程是关于怎么注册自己的网站域名账号和申请域名网址的流程的IT知识,下面为详细的介绍。 注册域名的一般流程是什么?个人申请域名流程需要知道哪些? 一、域名注册流程


