lombok @Builer.Default 需要注意的坑
最近在开发过程中,想让实体类中的boolean字段默认为true,于是我在字段定义后赋值为true,同时该类上有@Builder注解,我希望在使用builder方式创建实例的时候该字段也能默认为true,查看资料后发现@Builder.Default注解很合适。实际运行代码之后,我发现一个无奈的问题,builder模式下默认值生效了,但是使用new得到的实例默认值为false。贴上测试代码,清晰些。
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.NoArgsConstructor;
import lombok.ToString;
public class testLombok {
public static void main(String[] args) {
People p1 = new People();
System.out.println(p1); //People(old=false)
People p2 = People.builder().build(); //People(old=true)
System.out.println(p2);
}
}
@Builder
@ToString
@NoArgsConstructor
@AllArgsConstructor
class People {
@Builder.Default
private boolean old = true;
}
为什么会这样呢?心里一万头羊驼跑过…
我们来看反编译后的People代码
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
import java.beans.ConstructorProperties;
class People {
private boolean old;
private static boolean $default$old() {
return true;
}
public static People.PeopleBuilder builder() {
return new People.PeopleBuilder();
}
public String toString() {
return "People(old=" + this.old + ")";
}
public People() {
}
@ConstructorProperties({"old"})
public People(boolean old) {
this.old = old;
}
public static class PeopleBuilder {
private boolean old$set;
private boolean old;
PeopleBuilder() {
}
public People.PeopleBuilder old(boolean old) {
this.old = old;
this.old$set = true;
return this;
}
public People build() {
return new People(this.old$set ? this.old : People.$default$old());
}
public String toString() {
return "People.PeopleBuilder(old=" + this.old + ")";
}
}
}
从最开始看起,代码中old字段没有赋初值,并且多了一个static方法$default$old,方法的返回值即为设置的默认值。接着往后看,在静态内部类PeopleBuilder 中的build方法中对old字段进行了判断,如果没有被设置值,那么就将$default$old方法中的默认值赋给People实例。现在终于明白之前的困惑,并且顺带了解了@Builder.Default的实现原理。
既然@Builder.Default没有办法解决问题,那么该怎么办呢?
可以换个思路,实例初始化的时候,boolean字段会被初始化为false,利用这个特性把字段名字改为notOld即可。代码如下
public class People {
private boolean notOld;
}
还没有评论,来说两句吧...