当前位置:网站首页>Lombok原理和同时使⽤@Data和@Builder 的坑

Lombok原理和同时使⽤@Data和@Builder 的坑

2022-07-06 04:10:00 Hollis Chuang

来源:https://juejin.cn/post/7103011031672176677


问题背景

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

799c8da916b154a33e66619ebb6342f7.jpeg


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

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

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

29bfab8914410721eefb31e896652a6a.jpeg

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

6b233157c008fa6695752506b0db58e3.jpeg

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

30867a55d79a416d7e02e155c6f716f4.jpeg

编译后的class为:可以看到 已经帮我们构建好了全属性的构造方法,但是如果值只引用@Builder注解是无法生成get和set的。

7b7d96ffb1f7ce319f4ae0c3cf81a890.jpeg

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

fd263a4cde058ca1f83f04b9ed9c9094.jpeg

编译后的class:

fac1046184f80c0ffb0140248fc93918.jpeg

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

36feb04fc71ed757f6fbeac79b2a9644.jpeg

解决方法

方法一

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

0dca0674a3c2543d58b9f1e76861f2f1.jpeg

方法二

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

484cc355b2b7b0252ed932e3d2cc0613.jpeg

编译后效果:

7f512e04d355d3a4f7193f6c6ab12a98.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 ⾃定义⼀个注解,代码如下:

abe865620db6d05d6043b11d84a13301.jpeg

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

85be5b5d0a17bf9402a31663d90e50a7.jpegad99af6a06e0fe708ea57be5b70dc637.jpeg684c5a1fa8835a0eb83bccfacbcbbb95.jpeg

测试类如下:

295bf00de8a2c5e50da2c35b0c1284f8.jpeg

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

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

2a8fae00823a80af8cdb6c527e7f95aa.jpeg

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

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

7c0cb2d2450b9d65716b31876269611d.jpeg

348fdf918ea897cf1c6b3df05d946bec.jpeg

总结

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

往期推荐

35fe9580ad48427fc3410fabdeb79014.jpeg

如何搭建一支搞垮公司的技术团队?


1712ce63e39b34a546341a1f7765d8c7.jpeg

各大主流编程语言性能PK,结果出乎意料


9a63447dfec6f2d0d2fbfc73707cfca3.jpeg

金额计算用 BigDecimal 就万无一失了?看看这五个坑吧~~


有道无术,术可成;有术无道,止于术

欢迎大家关注Java之道公众号

1f049a9e84d6392f99a8e9263ea29a00.jpeg

好文章,我在看️

原网站

版权声明
本文为[Hollis Chuang]所创,转载请带上原文链接,感谢
https://hollis.blog.csdn.net/article/details/125630902