Java Lombok @Builder使用总结

我所使用的Lombok版本是1.18.8

一. @Builder与继承共存

     截止1.18.8版本,使用了@Builder注解的类仍然无法使用继承,

public class Test {
    public static void main(String[] args) {
        T1.builder().build();
    }
}

@Builder
@AllArgsConstructor
@NoArgsConstructor
@Setter
@Getter
class T1 extends T2{
    private String name;
    private Integer age;
}

@Builder
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
class T2{
    protected String pp;
}

     报错:

Error:(19, 1) java: com.mmr.learn.T1中的builder()无法覆盖com.mmr.learn.T2中的builder()
  返回类型com.mmr.learn.T1.T1Builder与com.mmr.learn.T2.T2Builder不兼容

     解决方案: 不使用@Builder注解到类上,创建T1的有参构造函数,入参不仅包括T1中所有的参数,还包括T中所有的参数。T2的属性由T1在有参构造函数中通过调用父类构造器的方式赋初值。

public class Test {
    public static void main(String[] args) {
        T1 t1 = T1.builder().name("java").pp("world").build();
        System.out.println(t1.getName());
        System.out.println(t1.getAge());
        System.out.println(t1.getPp());
    }
}

@AllArgsConstructor
@NoArgsConstructor
@Setter
@Getter
class T1 extends T2{
    private String name;
    private Integer age;

    @Builder(toBuilder = true)
    public T1(String pp, String name, Integer age) {
        super(pp);
        this.name = name;
        this.age = age;
    }
}

@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
class T2{
    protected String pp;
}

二. @Builder与属性赋初值

          就拿上面的案例来看,如果想对age赋初值,网上有的人将@Builder.Default 注解添加到待赋值属性上,如下图所示:

@Builder.Default
private Integer age = 26;

         在不涉及继承的场景中,这样用没有问题,因为@Builder.Default会为age在编译期间单独生成一个$default$age的方法,不仅在T1类内所有由Lombok自动生成的构造函数(比如使用@AllArgsConstructor或@NoArgsConstructor或@RequiredArgsConstructor等)中为age赋予了初值,而且还在T2Builder中也为其赋予了初值。因此,以下两种方式都能得到正确的结果:

System.out.println(T2.builder().build().getPp());
System.out.println(new T2().getPp());

         但一旦涉及到继承,此方法就不能使用了。从场景1(@Builder与继承共存)中,我们知道了想要兼容继承关系,@Builder不能加到类上,但实际上,@Builder.Default必须使用在一个被@Builder标识的类中,因此@Builder.Default注解用不了了。

         那该怎么办呢?很简单,我们在T1的有参构造函数中赋初值即可。

public class Test {
    public static void main(String[] args) {
        //输出: 25
        System.out.println(T1.builder().build().getAge());
        //输出: 26
        System.out.println(new T1().getAge());
    }
}

@AllArgsConstructor
@NoArgsConstructor
@Setter
@Getter
class T1 extends T2{
    private String name;
    private Integer age = 26;

    @Builder(toBuilder = true)
    public T1(String pp, String name, Integer age) {
        super(pp);
        this.name = name;
        if(null == age){
            this.age = 25;
        }else{
            this.age = age;
        }
    }
}

@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
class T2{
    protected String pp;
}
发布了45 篇原创文章 · 获赞 13 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/miaomiao19971215/article/details/103308540