Lombok同时使⽤@Data和@Builder遇到的坑
- Lombok是什么
- 有什么问题
- 不使用任何注解
- 只使用@Data注解
- 只使用@Builder注解
- 同时使用@Data和@Builder注解
- 如何解决
- @Builder和@NoArgsConstructor冲突
- 使用@AllArgsConstructor
Lombok是什么
Lombok 是一个 Java 库,它通过注解的方式帮助开发者减少在 Java 开发过程中的一些冗余代码,比如 getter、setter、equals、hashCode、toString 等方法的编写。使用 Lombok 可以让代码更加简洁和清晰。以下是一些常用的 Lombok 注解及其作用:
- @Data:为类添加 getter、setter、equals、hashCode 和 toString 方法。
- @AllArgsConstructor:为类中的所有字段生成构造器。
- @NoArgsConstructor:为类生成一个无参构造器。
- @ToString:生成 toString 方法。
- @EqualsAndHashCode:生成 equals 和 hashCode 方法。
- @Getter / @Setter:分别为类的所有字段生成 getter 和 setter 方法。也可以用在单个字段上。
- @NonNull:标记一个字段,在生成的 equals 方法中会检查该字段是否为 null。
- @Builder:生成一个构建器,用于创建类的实例,这个构建器支持按需设置类中的字段,使得对象的创建更加灵活。
有什么问题
好用是真的好用,但是遇到问题时也是真的让人懵,就比如 同时使⽤@Data和@Builder ,构建无参构造器报错!编译不通过
这样的问题,下面我们来看下造成这种问题的原因。
不使用任何注解
如下我们创建一个bean,不适用任何 Lombok 注解:
public class TestBean {private Integer id;private String name;
}
看一下编译之后的class文件如下图所示,即使是我们没用显示定义构造方法,Java编译器还是自动为我们生成了无参构造方法,这样的类才能通过构造函数创建对象。
但是想使用这个类,还是需要手动添加 get 和 set 方法才能设置属性值。
只使用@Data注解
当我们给 TestBean
类添加了 @Data
注解之后,再看下编译之后的 class
文件,Lombok 已经替我们添加了更多的方法如 toString()
、hashCode()
、equals()
等,我们可以正常使用 new 个对象,设置属性。
只使用@Builder注解
当我们给bean添加 @Builder 注解时,Lombok 替我们添加了如下内容:
- 默认访问权限的构造方法,是个全参构造函数,只能同一包内的类进行访问;
- builder() 方法,返回一个TestBeanBuilder对象,是链式调用的关键;
- TestBeanBuilder类,内部封装了链式调用的各种方法设置属性值,并借助 build() 方法调用全参构造函数创建bean。
其他包要使用这个类只能通过 builder()
方法来生成一个可链式调用的对象进行属性的定义,这也是建造者模式(Builder Pattern) 的一种便捷方式。
建造者模式是一种设计模式,用于解决对象创建时参数过多的问题,尤其是当对象有很多可选参数时。Lombok 的 @Builder 注解简化了建造者模式的实现,使得代码更加简洁和易读。
同时使用@Data和@Builder注解
当我们同时使用 @Data
和 @Builder
注解的时候,由于 Lombok 给我们默认生成了默认访问权限的全参构造函数,此时 Java 编译器就不会给我们提供默认的无参构造函数,所以我们还是只能使用链式调用的方式创建对接,调用无参构造函数时会报错。
如何解决
只能通过添加构造函数来创建对对象了,可以通过手动编写,也可以同注解的方式生成构造函数。
@Builder和@NoArgsConstructor冲突
当同时给类添加@Builder和@NoArgsConstructor注解时,会出现编译失败的问题,这是因为 Lombok 的 @Builder 注解需要一个合适的构造方法来生成构建器,而 @Builder
和 @NoArgsConstructor
注解在一起使用时,Lombok 无法自动生成合适的构造函数供 @Builder
使用。 @Builder
注解需要有一个全参构造函数,而 @NoArgsConstructor
注解会生成一个无参构造函数,导致冲突。
使用@AllArgsConstructor
因为 @Builder
需要一个全参构造函数,可以使用 @AllArgsConstructor
来生成一个全参构造函数,配合 @Builder
使用: