当前位置:网站首页>Lombok 同时使⽤ @Data 和 @Builder 的坑,你中招没?

Lombok 同时使⽤ @Data 和 @Builder 的坑,你中招没?

2022-07-06 16:47:00 Java精选

问题背景

Lombok使用 同时使用@Data@Builder ,构建无参构造器报错!编译不通过。如下图:

e6522753c8d4f4da18346074c0d868a0.jpeg

Lombok @Data和@Builder分别单独分析用法

Lombok使用@Data可以⽣成⽆参构造和类⾥⾯所有属性的getter/setter方法。可以简化我们代码的开发。(需要安装Lombok插件和引⼊Lombok依赖)。

例如下⾯的⼀个实体类,引⼊Lombok后,可以⾃动⽣成GET/SET方法和⽆参构造函数。

c321ea24ce42ccd388f772cdf7d41a6e.jpeg

编译后的class为:可以看到不仅帮我们生成了get和set ,同时也有默认的无参构造器

dcb0015aa7b0d4cab38fae6f728d86be.jpeg

那么怎么自动生成有参构造器呢?使用@Builder注解,将会帮助我们⽣成全属性的构造方法。

5c103f55acb173c747f16687a0bc9dda.jpeg

编译后的class为:可以看到 已经帮我们构建好了全属性的构造方法,但是如果值只引用@Builder注解是无法生成get和set的。另外,公众 号Java精选,回复java面试,获取面试资料。

e2b471d49ed92baf5b9f563f1153728a.jpeg

但是如果同时使用@Data@Builder的话,可以看出尽管⽣成了GET/SET方法,但是⽆参构造方法没有了,这显然是不能接受的,因为很多框架都会调用⽆参构造去创建对象。

d30043ce393093e57ef402da4338c5ec.jpeg

编译后的class:

3965c8eaa4823622e9f200bc594841dc.jpeg

我们尝试在Tet1类,⼿动添加⽆参构造方法。编译发现报错不通过:

92564806bbefcfa7f9be8907dade147c.jpeg

解决方法

方法一

Lombok同时使用@Data@Builder的时候,如果要⽣成⽆参构造,需要在代码⾥⾯⼿动引⼊注解@Tolerate,让Lombok在⽣成类的时候,对指定的构造函数不感知。

e9d12ea57de3c7ef72b4048bc936281e.jpeg

方法二

直接使用无参构造器+有参构造器的方式,@RequiredArgsConstructor 来构建有参,@NoArgsConstructor来构建无参构造器,如图所示:

cae48f435d036d19b52b8c2351663333.jpeg

编译后效果:

b4bcbeda0cabbe3b4ee4a77de7c66cb6.jpeg

Lombok原理

Java的编译分为以下⼏个阶段:

解析与填充符号表->注解处理->分析与字节码⽣成->⽣成⼆进制class⽂件。

  • Lombok 使用的是 JDK 6 实现的 JSR 269: Pluggable Annotation Processing API (编译期的注解处理器),它是在编译期时把 Lombok 的注解代码,转换为常规的 Java 方法⽽实现注⼊。

  • 在编译期阶段,当 Java 源码被抽象成语法树 (AST) 之后,Lombok 会根据⾃⼰的注解处理器动态的修改AST,增加新的代码 (节点),在这⼀切执⾏之后,再通过分析⽣成了最终的字节码 (.class) ⽂件,这就是Lombok 的执⾏原理。

可以借助注解处理器实现⼀个简单的 Setter,我们的实现步骤是:

  • 自定义⼀个注解标签接⼝,并实现⼀个⾃定义的注解处理器;

  • 利用 tools.jar 的 javac api 处理 AST (抽象语法树)3. 使用⾃定义的注解处理器编译代码。

1.定义自定义注解和注解处理器

⾸先创建⼀个 MySetter.java ⾃定义⼀个注解,代码如下:

da36a9d8aa55c34148092e7fbbe60e81.jpeg

再实现⼀个⾃定义的注解处理器,代码如下:

7db515f503baac991df403e6be9d21c5.jpegcae7570a93f1504a585f0d4802efcd3f.jpeg971d38a35d0030c8180ba855068f6d9d.jpeg

测试类如下:

69a72e5956f0a874cca0087727c43819.jpeg

2.对注解处理器进⾏编译,随后使用注解处理器对类进⾏编译

⾸先需要先对注解处理器进⾏编译(javac -cp 用于引⼊第三 jar包进⾏编译)

a7671e93eb86b0cb0c0764fd9c3b2866.jpeg

然后使用注解处理器对这个Person测试类进⾏编译:

这时候再看⽣成的Person.class,可以发现Setter方法已经⽣成了:

d26306dc67c4ab3587142be1c2d146a6.jpeg2956b4b1344a3f1293d813b185168622.jpeg

总结

当然尽管测试类已经⽣成Setter方法,但是因为是在编译时期⽣成的,因此我们在开发的时候是没法直接调用Setter方法的,因此Lombok提供了插件机制, 便我们在开发的时候可以直接去调用Lombok的特性。

作者:树洞君

https://juejin.cn/post/7103011031672176677

公众号“大咖笔记”所发表内容注明来源的,版权归原出处所有(无法查证版权的或者未注明出处的均来自网络,系转载,转载的目的在于传递更多信息,版权属于原作者。如有侵权,请联系,笔者会第一时间删除处理!

最近有很多人问,有没有读者交流群!加入方式很简单,公众号Java精选,回复“加群”,即可入群!

Java精选面试题(微信小程序):3000+道面试题,包含Java基础、并发、JVM、线程、MQ系列、Redis、Spring系列、Elasticsearch、Docker、K8s、Flink、Spark、架构设计等,在线随时刷题!

------ 特别推荐 ------

特别推荐:专注分享最前沿的技术与资讯,为弯道超车做好准备及各种开源项目与高效率软件的公众号,「大咖笔记」,专注挖掘好东西,非常值得大家关注。点击下方公众号卡片关注

文章有帮助的话,点在看,转发吧!

原网站

版权声明
本文为[Java精选]所创,转载请带上原文链接,感谢
https://blog.csdn.net/afreon/article/details/125631273