今天发现线上数据的某个字段被莫名更改了,找了一下原因,才发现使用 lombok 有很多注意事项。接下来一一讲述
@Builder 注意事项
类中字段默认值不会被直接使用
我们有个学生类代码如下:
其中学生类有一个 stuStatus 字段表示学生就读状态,默认值 1,表示默认是在读状态。当通过 builder()构建学生对象之后,如果不给 stuStatus 赋值,该字段的值并不是默认值 1,而是 int 的默认值 0;
@Data
@Builder
public class Student {
// 学生学号
private String stuNumber;
// 学生姓名
private String stuName;
// 学生状态(1: 在读 2: 离校) 默认是 1, 表示在读状态
private int stuStatus = 1;
}
public class TestStudent() {
@Test
public void testBuilder() {
// 以下代码构建完成之后,student 的 stuStatus 字段并不是默认值 1,而是 int 的默认值 0;Student student = Student.builder().build(); // Student{stuNumer:null,stuName:null,stuStatus:0}
}
}
为什么出现这种情况呢?
因为 lombok 在 builder()的时候如果没有显示的给字段赋值,那么这个字段的值就是 java 中的默认值(int:0 String:null 这种的),即使在类中给字段设置默认值也不生效。
如何解决呢?
在字段上使用 @Builder.Default 注解。
@Data
@Builder
public class Student {
// 学生学号
private String stuNumber;
// 学生姓名
private String stuName;
// 学生状态(1: 在读 2: 离校) 默认是 1, 表示在读状态
// import lombok.Builder.Default; 或者使用 @Builder.Default
@Default
private int stuStatus = 1;
}
public class TestStudent() {
@Test
public void testBuilder() {
// 以下代码构建完成之后,student 的 stuStatus 字段就是默认值 1
Student student = Student.builder().build(); // Student{stuNumer:null,stuName:null,stuStatus:1}
}
}
Lombok@Builder 代码分析
在 line110 ~ line 115 可以发现一个 @Default 注解。注释的意思就是:使用 @Default 注释的字段需要有一个初始化表达式(即我们字段的默认值),如果在生成期间没有显式的给该字段 set 值,则采取该值。
注:使用 @Builder 之后对于一些有意义的值最好显式赋值一下,如果想使用类中字段的默认值需要使用 @Default 注解。
构造函数:@Builder 会提供一个私有的全参构造方法
@Getter
@Setter
@Builder
public class Student {
// 学生学号
private String stuNumber;
// 学生姓名
private String stuName;
// 学生状态(1: 在读 2: 离校) 默认是 1, 表示在读状态
private int stuStatus = 1;
}
public class TestStudent() {
@Test
public void testBuilder() {
// 这段代码编译不通过,因为 @Builder 提供了一个私有的全参构造方法,就不会自动生成无参的构造方法
Student student = new Student();}
}
注: 在 @Builder 的注释中可以看到使用 @Builder 注解之后会默认的生成一个私有的全参构造方法,不会再生成一个无参构造方法,所以此时直接使用 new Studet()是会提示错误的。此时应该再提供使用一个注解 @NoArgsConstructor,提供一个无参构造方法。