关于java:Lombok-同时使用-Data-和-Builder-的巨坑千万别乱用

55次阅读

共计 1614 个字符,预计需要花费 5 分钟才能阅读完成。

起源:juejin.cn/post/7103011031672176677

问题背景

Lombok 同时应用 @Data 和 @Builder,会呈现构建无参结构器报错!最终导致编译不通过。如下图:

Lombok @Data 和 @Builder 别离独自剖析用法

Lombok 使⽤ @Data 能够⽣成⽆参结构和类⾥⾯所有属性的 getter/setter ⽅法。能够简化咱们代码的开发。(须要装置 Lombok 插件和引⼊ Lombok 依赖)。

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

编译后的 class 为: 能够看到不仅帮咱们生成了 get 和 set,同时也有默认的无参结构器

那么怎么主动生成有参结构器呢?应用 @Builder 注解,将会帮忙咱们⽣成全属性的构造方法。

编译后的 class 能够看到 曾经帮咱们构建好了全属性的构造方法,然而如果值只援用 @Builder 注解是无奈生成 get 和 set 的。

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

编译后的 class:

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

最新 Java 开发工具教程:https://www.javastack.cn/devtools/

解决办法

办法一

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

办法二

间接应用无参结构器 + 有参结构器的形式,@RequiredArgsConstructor 来构建有参,@NoArgsConstructor 来构建无参结构器,如图所示:

编译后成果:

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

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

测试类如下:

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

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

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

这时候再看⽣成的 Person.class,能够发现 Setter ⽅法曾经⽣成了:

总结

当然只管测试类曾经⽣成 Setter ⽅法,然而因为是在编译期间⽣成的,因而咱们在开发的时候是没法间接调⽤ Setter ⽅法的,因而 Lombok 提供了插件机制,⽅便咱们在开发的时候能够间接去调⽤ Lombok 的个性。

近期热文举荐:

1.1,000+ 道 Java 面试题及答案整顿 (2022 最新版)

2. 劲爆!Java 协程要来了。。。

3.Spring Boot 2.x 教程,太全了!

4. 别再写满屏的爆爆爆炸类了,试试装璜器模式,这才是优雅的形式!!

5.《Java 开发手册(嵩山版)》最新公布,速速下载!

感觉不错,别忘了顺手点赞 + 转发哦!

正文完
 0