一、序言
对于 Lombok 的使用是有争议的,作者对 Lombok 的态度是强烈推荐,甚至认为应当将部分常用功能直接以 JDK 的形式集成。
在构建实体类过程中写一堆Set/Get
方法毫无意义;默认继承Object
类的toString
方法官方建议重写,每个实体类为了表达具象的实体信息而重写toString
方法,操作繁琐。
二、常用注解解析
下面讨论的注解是添加到实体类上面的。
public
class
XUser
{
private
Integer userId
;
private
String userName
;
}
添加@Data
注解后,编译后的实体类自动增加如下信息:属性的Set/Get
方法,变化后自动增减;默认构造器,其中equals
方法、hashCode
方法、toString
方法由 Lombok 重写。后面会详细讨论其重写逻辑。
添加@AllArgsConstructor
注解后,编译后的实体自动增加如下信息:全参构造器。添加完@AllArgsConstructor
注解后,一般都需要无参构造器的注解@NoArgsConstructor
。
在添加完@AllArgsConstructor
注解后,增加@NoArgsConstructor
后实体类变化如下:
添加@ToString
注解后,编译后的实体自动增加如下信息:重写的toString
方法。
@ToString
注解在@Data
注解存在的情况下是不需要额外添加的,除非是需要用到其属性配置。常用的属性配置为callSuper = true
表示将父类的属性值一起添加至重写的toString
方法中。
添加@Builder
注解后,编译后的实体自动增加如下信息:链式Set
方法。
链式 Set 方法的优点如下:
// 用简洁的方式实例化实体类并完成赋值操作
XUser xUser
=
XUser.builder().userId(1).userName("AAAAA").build();
添加@Accessors(chain = true)
注解后,编译后的实体类变化如下:setXxx
方法是有返回值的,并且是当前对象的示例。使用此注解需要注意三点:
- 此注解属于试验型的,可能后期会删除;
- 此注解将属性
chain
设置为true
是效果生效的必要条件之一; - 配合
@Data
注解或者@Setter
注解使用是效果生效的必要条件。
@Setter
@Accessors(chain
=
true)
public
class
XUser
{
private
Integer userId
;
private
String userName
;
}
主要参数介绍
参数 | 默认值 | 注释 |
|
| 控制生成的 getter 和 setter 方法前面是否带 get/set。如果为 |
|
| 如果设置为 |
参数fluent
应谨慎使用,对于 Jackson 序列化框架,不带 get/set 前缀的方法有不识别的概率。
上面提到的是针对实体类常用的注解,此处主要讲服务类注解。两者并没有明显的界限区分,理论上都能使用,本处仅仅是根据使用场合进行区分。
类添加完@Log4j2
注解后,当前类实例自动持有log
成员变量,可以通过此变量增加日志信息。
@Log4j2
public
class
XUserServiceImpl
{
public
void
saveUser(XUser user
)
{
log
.info("此方法保存用户信息");
}
}
类信息变化如下:
三、过程探究
Lombok 中的部分注解会重写下列方法:equals
方法、hashCode
方法、toString
(1)默认实现
默认继承超类Object
的实现
public
String
toString()
{
return
getClass().getName()
+
"@"
+
Integer.toHexString(hashCode());
}
示例
XUser xUser
=
new
XUser();
System.out
.println(xUser
.toString());
System.out
.println(xUser
.toString());
同一个实例的输出结果一致
xin.altitude.lombok.domain.XUser@43d7741f
xin.altitude.lombok.domain.XUser@43d7741f
(2)重写实现
示例
System.out
.println(new
XUser(1,"AAAAA").toString());
System.out
.println(new
XUser(1,"AAAAA").toString());~
相同的成员变量输出值一致,只有当成员变量不同时,输出结果才有差异,与执行次数无关,与实例对象引用无关。
XUser(userId=1, userName=AAAAA)
XUser(userId=1, userName=AAAAA)
(1)默认实现
默认继承超类Object
的实现
public
boolean
equals(Object obj
)
{
return
(this
== obj
);
}
示例
XUser xUser1
=
new
XUser(1,
"AAAAA");
XUser xUser2
= xUser1
;
// 在同一个JVM中,相同的引用对象实例相同(输出为true)
boolean bl
= xUser1
.equals(xUser2
);
(2)重写实现
示例
// 对象的属性值是否相等(输出是true)
boolean bl
=
new
XUser(1,
"AAAAA").equals(new
XUser(1,
"AAAAA"));
相同的成员变量构造出对象使用重写后的equals
方法,无论执行多少次,结果都为true
。
看完如果有帮助,希望可以给个 三连 ,你的鼓励就是我不断前进的动力。谢谢
关注我:私信获取Java高级架构资料、大厂面试试题、视频