Lombok中@Builder和@SuperBuilder注解的用法

@Builderlombok 中的注解。可以使用builder()构造的Person.PersonBuilder对象进行链式调用,给所有属性依次赋值。

    Person person1 = Person.builder()
            .name("张三")
            .age(20)
            .build();
    System.out.println(person1);                // Person(name=张三, age=20)
    System.out.println(Person.builder());       // Person.PersonBuilder(name=null, age=null)

文档中给了案例,在实体类上添加 @Builder 后,实体类会被改造成如下的结构:

Before:
  @Builder
  class Example {
    private T foo;
    private final String bar;
  }

After:
  class Example {
    private T foo;
    private final String bar;

    // 私有的全参数构造函数
    private Example(T foo, String bar) {
        this.foo = foo;
        this.bar = bar;
    }

    public static  ExampleBuilder builder() {
        return new ExampleBuilder();
    }

    public static class ExampleBuilder {
        private T foo;
        private String bar;

        private ExampleBuilder() {}

        public ExampleBuilder foo(T foo) {
            this.foo = foo;
            return this;
        }

        public ExampleBuilder bar(String bar) {
            this.bar = bar;
            return this;
        }

        @java.lang.Override public String toString() {
            return "ExampleBuilder(foo = " + foo + ", bar = " + bar + ")";
        }

        public Example build() {
            return new Example(foo, bar);
        }
    }
  }

源码如下:

@Target({TYPE, METHOD, CONSTRUCTOR})
@Retention(SOURCE)
public @interface Builder {

    @Target(FIELD)
    @Retention(SOURCE)
    public @interface Default {}

    String builderMethodName() default "builder";

    String buildMethodName() default "build";

    String builderClassName() default "";

    boolean toBuilder() default false;

    AccessLevel access() default lombok.AccessLevel.PUBLIC;

    String setterPrefix() default "";

    @Target({FIELD, PARAMETER})
    @Retention(SOURCE)
    public @interface ObtainVia {

        String field() default "";

        String method() default "";

        boolean isStatic() default false;
    }
}

@Singular 注解修饰集合

该注解默认变量的名称是一个复数,并且尝试生成该变量的奇数形式。例如 List skills,会添加3个方法:

  • skill(String skill) 添加单个元素
  • skills(List skillList) 添加一个集合
  • clearSkills() 清空集合,并且将未初始化的集合初始化未空集合。

如果无法计算得到变量名称的奇数形式,则会提示报错信息。用户可以手动指定单数形式的方法名:

    @Singular("skill")
    private List skillList;

这时会生成skill(String skill)skillList(List skillList)clearSkillList()三个方法。

@Builder.Default

使用 @Builder.Default 设置默认值,构建对象时可以不用调用`name()方法。(调用后会覆盖默认值)

    @Builder.Default
    private String name = "zhangsan";

@SuperBuilder

@Builder 注解无法解析父类的属性,而@SuperBuilder可以读取父类的属性。使用时需要在子类和父类上都加上这个注解

@SuperBuilder
public class Male extends Person{
}

@SuperBuilder
public class Person {
    @Builder.Default
    private String name = "zhangsan";

    private Integer age;

    @Singular("skillList")
    private List skillList;
}

@SuperBuilder(toBuilder=true)

使用 @SuperBuilder(toBuilder=true) 可以使用已有的对象构建新的对象,旧对象的属性值会被保留和覆盖。注意: 子类和父类都需要加上toBuilder=true

        Male man = Male.builder()
                .name("张三")
                .age(20)
                .build();

        Male man2 = man.toBuilder()
                .age(30)
                .build();

文章来源于互联网:Lombok中@Builder和@SuperBuilder注解的用法

THE END
分享
二维码