Lombok @Data 注解:一键生成代码
一则或许对你有用的小广告
最近,小哈正在带小伙伴们做前后端分离博客项目,采用技术栈 Spring Boot + Mybatis Plus + Vue 3.2 + Vite 4
,手把手,前端 + 后端,全栈开发,从 0 到 1 讲解每个功能点开发步骤,1v1 答疑,陪伴式直到项目上线,目前已进入第七章 《文章分类模块开发》中,截止到目前,已更新 105150 字,69 篇内容,讲解图:521 张,还在持续爆肝中,后续还会上新更多项目,已有 200+ 小伙伴加入,欢迎点击围观。
一 、什么是 Lombok @Data 注解?
在 Lombok 中,@Data
是个万金油注解。一个 @Data
注解相当于同时使用了 @Getter
、@Setter
、@RequiredArgsConstructor
、@ToString
、@EqualsAndHashCode
。
Lombok @Data 注解
二、对比编译后的源码
先来看看下面这两段 Lombok 注解使用示例:
@Getter
@Setter
@RequiredArgsConstructor
@ToString
@EqualsAndHashCode
public class User1 {
private Long id;
private String username;
// 更多字段省略 ...
}
@Data
public class User2 {
private Long id;
private String username;
// 更多字段省略 ...
}
编译代码,看看 Lombok 为这两个实体类生成的代码:
User1.java :
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package com.quanxiaoha.coursefrontend.model;
public class User1 {
private Long id;
private String username;
public Long getId() {
return this.id;
}
public String getUsername() {
return this.username;
}
public void setId(final Long id) {
this.id = id;
}
public void setUsername(final String username) {
this.username = username;
}
public User1() {
}
public String toString() {
return "User1(id=" + this.getId() + ", username=" + this.getUsername() + ")";
}
public boolean equals(final Object o) {
if (o == this) {
return true;
} else if (!(o instanceof User1)) {
return false;
} else {
User1 other = (User1)o;
if (!other.canEqual(this)) {
return false;
} else {
Object this$id = this.getId();
Object other$id = other.getId();
if (this$id == null) {
if (other$id != null) {
return false;
}
} else if (!this$id.equals(other$id)) {
return false;
}
Object this$username = this.getUsername();
Object other$username = other.getUsername();
if (this$username == null) {
if (other$username != null) {
return false;
}
} else if (!this$username.equals(other$username)) {
return false;
}
return true;
}
}
}
protected boolean canEqual(final Object other) {
return other instanceof User1;
}
public int hashCode() {
int PRIME = true;
int result = 1;
Object $id = this.getId();
result = result * 59 + ($id == null ? 43 : $id.hashCode());
Object $username = this.getUsername();
result = result * 59 + ($username == null ? 43 : $username.hashCode());
return result;
}
}
User2.java :
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package com.quanxiaoha.coursefrontend.model;
public class User2 {
private Long id;
private String username;
public User2() {
}
public Long getId() {
return this.id;
}
public String getUsername() {
return this.username;
}
public void setId(final Long id) {
this.id = id;
}
public void setUsername(final String username) {
this.username = username;
}
public boolean equals(final Object o) {
if (o == this) {
return true;
} else if (!(o instanceof User2)) {
return false;
} else {
User2 other = (User2)o;
if (!other.canEqual(this)) {
return false;
} else {
Object this$id = this.getId();
Object other$id = other.getId();
if (this$id == null) {
if (other$id != null) {
return false;
}
} else if (!this$id.equals(other$id)) {
return false;
}
Object this$username = this.getUsername();
Object other$username = other.getUsername();
if (this$username == null) {
if (other$username != null) {
return false;
}
} else if (!this$username.equals(other$username)) {
return false;
}
return true;
}
}
}
protected boolean canEqual(final Object other) {
return other instanceof User2;
}
public int hashCode() {
int PRIME = true;
int result = 1;
Object $id = this.getId();
result = result * 59 + ($id == null ? 43 : $id.hashCode());
Object $username = this.getUsername();
result = result * 59 + ($username == null ? 43 : $username.hashCode());
return result;
}
public String toString() {
return "User2(id=" + this.getId() + ", username=" + this.getUsername() + ")";
}
}
通过对比,会发现两个类生成的代码一致,包含:
- 生成了所有字段的
get/set
方法; - 实体类的无参构造器;
toString()
方法;hashCode()
方法;equals()
方法;
三、Lombok @Data 注解是何时工作的?
Lombok @Data
注解会告诉 IDE (如 IntellJ、Eclipse) ,或者你的构建工具(如 Maven、Ant),在代码的编译期间为你静默生成相关样板代码。
四、staticConstructor 参数
先看一段示例代码:
@Data(staticConstructor = "create")
public class User2 {
private Long id;
private String username;
// 更多字段省略 ...
}
如果你为 @Data
注解指定了 staticConstructor
参数,再次编译代码,看看实际生成的代码:
Lombok staticConstructor
由图可知,@Data(staticConstructor = "create")
生成了一个名为 create()
静态实体类生成方法,同时私有化了无参构造器。
五、Lombok @Data 排除指定字段
@Data
注解生成的模板方法中,默认会带上所有字段,如果针对某个字段不想生成 get/set
方法,或者是 toString()
、equals()
、hashCode()
方法排除某个字段的判断,示例代码如下:
@Data
public class User3 {
// 不生成此字段的 set 方法
@Setter(value = AccessLevel.NONE)
private Long id;
// 不生成此字段的 get 方法
@Getter(value = AccessLevel.NONE)
private String username;
// toString() 方法中不打印此字段
@ToString.Exclude
private String email;
// 1. equals() 和 hashCode() 方法中排除此字段的判断
// 2. toString() 方法中不打印此字段
@EqualsAndHashCode.Exclude
@ToString.Exclude
private Integer sex;
}
六、关于 Lombok 参数构造器
如果仅添加 @Data 注解,默认只会生成一个无参的构造器;当同时添加 @Data
和 @Builder
注解时,仅会生成一个全参构造器。小哈在日常项目中,通常会在实体类上额外添加 @AllArgsConstructor
、@NoArgsConstructor
注解, 示例代码如下:
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class User4 {
private Long id;
private String username;
// 更多字段省略 ...
}
这样,该实体类就基本拥有了常用的一些模板方法,包括 builder
构造器模式、无参构造器、全参构造器等。
七、结语
本小节中,我们学习了 Lombok 的 @Data 注解,以及通过简单的代码示例,知道了如何在项目中使用它。总之,Lombok 是一个被广泛应用于生产环境的成熟工具,它可以帮助开发者生成实体类通用的一些样板代码,从而帮助我们节省大量的开发时间,还没有使用它的小伙伴们,可以赶快安排上了。