Lombok 同时使用 @Data 和 @Builder 的坑

问题背景

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类,手动添加无参构造方法。编译发现报错不通过:

图片

解决方法

方法一

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 (抽象语法树)
  • 使用自定义的注解处理器编译代码。

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

先创建一个 MySetter.java 自定义一个注解,代码如下:

图片

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

图片

图片

图片

测试类如下:

图片

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

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

图片

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

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

图片

图片

总结

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

猜你喜欢

转载自blog.csdn.net/qq_43842093/article/details/131737725