目录
1. 项目环境
- IDEA 2020.1.4
- Maven 3.6
- JDK 1.8
- SpringBoot 2.x
项目文件在GitHub(欢迎star⭐):
https://github.com/Gang-bb/Gangbb-SpringBoot
如有疑问或是建议,欢迎评论区留言或者QQ:949526365
lombok官方文档:https://projectlombok.org/features/all
2.添加依赖和安装插件
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
好像Lombok的Idea插件不可以离线安装,晕!
3. 实体类常用注解总结
3.1 @Setter、@Getter
为变量默认生成public的get、set方法,我们也可以指定 访问控制修饰符。
使用后默认生成一个无参的构造函数。
对final变量只会生成get方法、set不会;statis变量不会生成get或set方法!
3.1.1 注解在属性上
编译后的代码:
3.1.2 注解在类上
类中所有非静态属性都生成set、get方法
编译后:
可以指定不生成get或set的属性:
编译后:
3.1.3 注解对静态属性和final类型属性
编译后:
3.2 @NoArgsConstructor
生成无参构造函数
编译后:
3.3 @AllArgsConstructor
该注解提供一个全参数的构造方法,默认不提供无参构造。
编译后:
3.4 @RequiredArgsConstructor
将标记为@NoNull
和final
的属性生成一个构造器。
所有未初始化的 final
字段,以及未初始化的用 @NonNull
标记的字段,都会获得一个参数。对于标有 @NonNull
的字段,还会生成显式空检查。如果用于标记为 @NonNull
的字段的任何参数是 null
,则构造函数将抛出 NullPointerException
。参数的顺序与字段在类中的显示顺序相匹配。
编译后:
3.5 @ToString
该注解应用在类上,为我们生成Object的toString方法。生成全部参数的toString()
编译后:
使用excledu和of自定义toString()中的参数:
exclude属性禁止在toString方法中使用某字段,而of可以指定需要使用的字段。如果使用了这两属性,未出现在这两属性声明中的类变量默认是排除在外。
编译后:
3.6 @EqualsAndHashCode
生成equals()方法和hashCode方法
该注解应用在类上,lombok会为我们生成equals(Object other)和hashCode()方法,包括所有非静态属性和非transient的属性;同样可以使用exclude属性禁止在toString方法中使用某字段,而of可以指定需要使用的字段;也可以通过callSuper属性在重写的方法中使用父类的字段,这样我们可以更加灵活的定义bean的比对,如下图:
编译后:
public class User2 {
private String type;
private Integer id;
private String remark;
private String age;
public User2() {
}
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 {
label59: {
Object this$id = this.id;
Object other$id = other.id;
if (this$id == null) {
if (other$id == null) {
break label59;
}
} else if (this$id.equals(other$id)) {
break label59;
}
return false;
}
Object this$type = this.type;
Object other$type = other.type;
if (this$type == null) {
if (other$type != null) {
return false;
}
} else if (!this$type.equals(other$type)) {
return false;
}
Object this$remark = this.remark;
Object other$remark = other.remark;
if (this$remark == null) {
if (other$remark != null) {
return false;
}
} else if (!this$remark.equals(other$remark)) {
return false;
}
Object this$age = this.age;
Object other$age = other.age;
if (this$age == null) {
if (other$age != null) {
return false;
}
} else if (!this$age.equals(other$age)) {
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.id;
int result = result * 59 + ($id == null ? 43 : $id.hashCode());
Object $type = this.type;
result = result * 59 + ($type == null ? 43 : $type.hashCode());
Object $remark = this.remark;
result = result * 59 + ($remark == null ? 43 : $remark.hashCode());
Object $age = this.age;
result = result * 59 + ($age == null ? 43 : $age.hashCode());
return result;
}
}
3.7 @Data(常用)
@Data=@Setter+@Getter+@EqualsAndHashCode+@NoArgsConstructor+@RequiredArgsConstructor
- 所有生成的 getter 和 setter 都将是
public
的。要覆盖访问级别,请使用显式的@Setter
和/或@Getter
注解对字段或类进行注释。你还可以使用此注解(通过将其与AccessLevel.NONE
组合)来完全禁止生成 getter 和/或 setter。 - 标记为
transient
的所有字段都不会被hashCode
和equals
考虑。将完全跳过所有静态字段(不考虑任何生成的方法,并且不会为它们创建 setter / getter)。 - 针对其
equals()
方法,当它进行属性比较时,其实只比较了当前类中的属性。如果两个子类对象,其子类中的属性相同、父类中的属性不同时,利用equals()
方法时,依旧会认为这两个对象相同。用了@Data
就不要有继承关系。
编译后:
public class Data {
private String type;
private Integer id;
private String remark;
private Integer age;
private Boolean status;
private Long other_id;
public Data() {
}
public String getType() {
return this.type;
}
public Integer getId() {
return this.id;
}
public String getRemark() {
return this.remark;
}
public Integer getAge() {
return this.age;
}
public Boolean getStatus() {
return this.status;
}
public Long getOther_id() {
return this.other_id;
}
public void setType(final String type) {
this.type = type;
}
public void setId(final Integer id) {
this.id = id;
}
public void setRemark(final String remark) {
this.remark = remark;
}
public void setAge(final Integer age) {
this.age = age;
}
public void setStatus(final Boolean status) {
this.status = status;
}
public void setOther_id(final Long other_id) {
this.other_id = other_id;
}
public boolean equals(final Object o) {
if (o == this) {
return true;
} else if (!(o instanceof Data)) {
return false;
} else {
Data other = (Data)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$age = this.getAge();
Object other$age = other.getAge();
if (this$age == null) {
if (other$age != null) {
return false;
}
} else if (!this$age.equals(other$age)) {
return false;
}
Object this$status = this.getStatus();
Object other$status = other.getStatus();
if (this$status == null) {
if (other$status != null) {
return false;
}
} else if (!this$status.equals(other$status)) {
return false;
}
label62: {
Object this$other_id = this.getOther_id();
Object other$other_id = other.getOther_id();
if (this$other_id == null) {
if (other$other_id == null) {
break label62;
}
} else if (this$other_id.equals(other$other_id)) {
break label62;
}
return false;
}
label55: {
Object this$type = this.getType();
Object other$type = other.getType();
if (this$type == null) {
if (other$type == null) {
break label55;
}
} else if (this$type.equals(other$type)) {
break label55;
}
return false;
}
Object this$remark = this.getRemark();
Object other$remark = other.getRemark();
if (this$remark == null) {
if (other$remark != null) {
return false;
}
} else if (!this$remark.equals(other$remark)) {
return false;
}
return true;
}
}
}
protected boolean canEqual(final Object other) {
return other instanceof Data;
}
public int hashCode() {
int PRIME = true;
int result = 1;
Object $id = this.getId();
int result = result * 59 + ($id == null ? 43 : $id.hashCode());
Object $age = this.getAge();
result = result * 59 + ($age == null ? 43 : $age.hashCode());
Object $status = this.getStatus();
result = result * 59 + ($status == null ? 43 : $status.hashCode());
Object $other_id = this.getOther_id();
result = result * 59 + ($other_id == null ? 43 : $other_id.hashCode());
Object $type = this.getType();
result = result * 59 + ($type == null ? 43 : $type.hashCode());
Object $remark = this.getRemark();
result = result * 59 + ($remark == null ? 43 : $remark.hashCode());
return result;
}
public String toString() {
return "Data(type=" + this.getType() + ", id=" + this.getId() + ", remark=" + this.getRemark() + ", age=" + this.getAge() + ", status=" + this.getStatus() + ", other_id=" + this.getOther_id() + ")";
}
}
3.8 @Builder
构造Builder模式的结构。通过内部类Builder()进行构建对象,使用该注解后默认生成全参toString()
@Builder
允许你使用以下代码自动生成使你的类可实例化所需的代码:
Person.builder().name("Adam Savage").city("San Francisco").job("Mythbusters").job("Unchained Reaction").build();
编译后:
public class User3 {
private String type;
private Integer id;
private String remark;
User3(final String type, final Integer id, final String remark) {
this.type = type;
this.id = id;
this.remark = remark;
}
public static User3.User3Builder builder() {
return new User3.User3Builder();
}
public static class User3Builder {
private String type;
private Integer id;
private String remark;
User3Builder() {
}
public User3.User3Builder type(final String type) {
this.type = type;
return this;
}
public User3.User3Builder id(final Integer id) {
this.id = id;
return this;
}
public User3.User3Builder remark(final String remark) {
this.remark = remark;
return this;
}
public User3 build() {
return new User3(this.type, this.id, this.remark);
}
public String toString() {
return "User3.User3Builder(type=" + this.type + ", id=" + this.id + ", remark=" + this.remark + ")";
}
}
}
使用:
3.9 @Value
与@Data相对应的@Value, 两个annotation的主要区别就是如果变量不加@NonFinal ,@Value会给所有的弄成final的。当然如果是final的话,就没有set方法了。
详解:https://github.com/codercuixin/lombok-translate/wiki/@Value
3.10 @NonNull
该注解使用在属性上,该注解用于属的非空检查,当放在setter方法的字段上,将生成一个空检查,如果为空,则抛出NullPointerException。
该注解会默认是生成一个无参构造。
4. 其他常用注解
4.1 日志相关@Slf4j
@Slf4j使用
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class LogExample {
}
以上将编译成
public class LogExample {
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LogExample.class);
}
使用:
推荐使用log4j2作为日志实现,相关配置和整合:
SpringBoot系列-- SpringBoot整合SLF4j+log4j2+aop记录web请求
5.后话
lombok可以说是有利有弊,网上也有很多大佬,完整分析的利弊。个人认为用不用还是得看公司的开发规范或者你的队友用了你就被他QJ了,必须得用…(我第一次用就是队友用了,看他的代码就必须得用)
我自己平时写一些demo会用到,其他场景就看所处环境了!
不过学无止境,技术能多了解一点总是没错。不一定必须得用,但在大环境下你必须得了解过!