在日常工作中,使用 Lombok 主要还是用于 Bean、POJO、DTO 一类,还是挺好用的。
建议使用 Lombok 1.18.xx 以上版本,支持 @SuperBuilder
注解,这也是 SpringBoot 2.1.X 开始采用的新版本。
注解
@NoArgsConstructor
提供一个无参数构造器。
如果我们需要使用到单例模式,(很少,一般使用 Lombok 都是用作POJO、DTO),可以设置 (access = AccessLevel.PRIVATE)。
如果包含 final 成员,会导致编译错误。可以强制使用 (force = true),从而对 final 进行默认初始化(0/false/null)。
对 @NonNull
注解的字段,不做任何检查。
@RequiredArgsConstructor
提供无参数或有参数的构造器。
当包含 final 成员,和 @NonNull
注解的字段,会生成带参数的构造器。
所以这个注解相对使用起来比 @NoArgsConstructor
更安全。
@AllArgsConstructor
提供一个全参数的构造器。
@Data
组合了这些注解 @ToString
、@EqualsAndHashCode
、@Getter
、@Setter
、@RequiredArgsConstructor
@Builder
提供了建造者模式。会默认生成一个私有的 @AllArgsConstructor
注意: 当与
@Data
一起使用的时候,会丢失无参构造器。作者认为如果使用@Builder
,原则上你不太需要使用 new 来进行创建对象。然而目前有很多框架是使用反射无参构造器来创建对象的,所以会产生问题。
解决方法: 如果有问题,可以手动增加
@NoArgsConstructor
,@AllArgsConstructor
注解
@Builder.Default
指定建造者模式的默认值,否则未初始化的值默认是 null
常见问题
Lombok 的继承,会有一些问题。
有继承关系时的 @Data
默认情况下 @Data
仅仅比较子类的值,并且 toString
方法也没有父类信息,如下所示:
1 |
|
看下示例代码,调用 equals 结果是 true:
1 | UserChild userChild11 = new UserChild(); |
解决方案:
在子类上增加 @ToString(callSuper = true)
和 @EqualsAndHashCode(callSuper = true)
@Builder (1.18 版本以前)
在子类增加 @Builder,建造者模式只能作用于子类成员,无法应用到父类。
在 1.18 版本以前,只能通过很丑陋的方式来进行子类的 .builder(),这完全丢失了 lombok 的便捷性:
取消父子类的类级别 @Builder
自定义子类的构造器,初始化父类成员和子类成员,并且使用 @Builder 注解
1 |
|
@SuperBuilder (1.18 版本之后)
父类子类都使用 @SuperBuilder 就可以简单的实现。
1 |
|
1.18.X 版本
Lombok 1.18.X 引入了一个不兼容的变更(为了兼容 Java 9 的 Module):
当我们同时使用 @Data 与 @Builder 时, Jackson 反序列化时会报错 ,比如如下代码在 1.16.22 工作正常,但是在 1.18.X 时报 (no Creators, like default construct, exist):
1 |
|
解决方案:
给类额外添加 @NoArgsConstructor
, @AllArgsConstructor
注解