lombok中的@Builder.Default注解

lombok中的@Builder.Default注解为成员变量赋默认值
(1)只对成员变量设置默认值,builder构造默认值是无效的

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Student {
    private Integer age = 2;
    private String name;
}

如果我们用,java的new操作,是会对Student设置默认值的

Student s = new Student();
// Student(age=2, name=null)

但是Builder是无效的

Student s = Student.builder().build();
Student(age=null, name=null)

原因在于,编译生成的Student.class文件,保留了成员变量的初始值,但是在StuentBuilder中,只有成员变量,而没有默认值

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

import java.beans.ConstructorProperties;
import java.io.Serializable;

public class Student implements Serializable {
    private Integer age = 2;
    private String name;

    @ConstructorProperties({"age", "name"})
    Student(Integer age, String name) {
        this.age = age;
        this.name = name;
    }

    public static Student.StudentBuilder builder() {
        return new Student.StudentBuilder();
    }

    public static class StudentBuilder {
        private Integer age;
        private String name;

        StudentBuilder() {
        }

        public Student.StudentBuilder age(Integer age) {
            this.age = age;
            return this;
        }

        public Student.StudentBuilder name(String name) {
            this.name = name;
            return this;
        }

        public Student build() {
            return new Student(this.age, this.name);
        }

        public String toString() {
            return "Student.StudentBuilder(age=" + this.age + ", name=" + this.name + ")";
        }
    }
}

(2)设置@Builder.Default注解后,通过标识判断是否启用默认值

@Builder
public class Student implements Serializable {
    @Builder.Default
    private Integer age = 2;
    private String name;
}
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

import java.beans.ConstructorProperties;
import java.io.Serializable;

public class Student implements Serializable {
    private Integer age;
    private String name;

    private static Integer $default$age() {
        return 2;
    }

    @ConstructorProperties({"age", "name"})
    Student(Integer age, String name) {
        this.age = age;
        this.name = name;
    }

    public static Student.StudentBuilder builder() {
        return new Student.StudentBuilder();
    }

    public static class StudentBuilder {
        private boolean age$set;
        private Integer age;
        private String name;

        StudentBuilder() {
        }

        public Student.StudentBuilder age(Integer age) {
            this.age = age;
            this.age$set = true;
            return this;
        }

        public Student.StudentBuilder name(String name) {
            this.name = name;
            return this;
        }

        public Student build() {
            return new Student(this.age$set ? this.age : Student.$default$age(), this.name);
        }

        public String toString() {
            return "Student.StudentBuilder(age=" + this.age + ", name=" + this.name + ")";
        }
    }
}

可以看到编译生成的.class文件,没有对age设置默认值。所以new出现的对象肯定没有设置默认值。
其次,通过引入标识age$set,判断是否启用默认值

public Student build() {
     return new Student(this.age$set ? this.age : Student.$default$age(), this.name);
}

this.age$set默认是false,只有在

public Student.StudentBuilder age(Integer age) {
      this.age = age;
      this.age$set = true;
      return this;
 }

中才对其进行赋值为true
也就是说,如果不调用Student s = Student.builder().age(4).build();age$setfalse,执行Student.$default$age()方法,设置默认值。否则,获取this.age

【总结】
(1)不用@Builder.Default,为成员变量设置默认值,new出来的对象自带默认值
(2)启用@Builder.Default,new出来的对象为空对象,不带默认值
(3)启用@Builder.Default,不设置-> Student.builder().build(),为默认值
(4)启用@Builder.Default,设置-> Student.builder().age(4).build(),为设置的值
关键看Student.class文件

你可能感兴趣的:(lombok中的@Builder.Default注解)