今天发现线上数据的某个字段被莫名更改了,找了一下原因,才发现使用lombok有很多注意事项。接下来一一讲述
@Builder注意事项
类中字段默认值不会被直接使用
我们有个学生类代码如下:
其中学生类有一个stuStatus字段表示学生就读状态,默认值1,表示默认是在读状态。当通过builder()构建学生对象之后,如果不给stuStatus赋值,该字段的值并不是默认值1,而是int的默认值0;
@Data@Builderpublic 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@Builderpublic 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@Builderpublic 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,提供一个无参构造方法。