乐趣区

Lombok使用注意事项

今天发现线上数据的某个字段被莫名更改了,找了一下原因,才发现使用 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,提供一个无参构造方法。

退出移动版