Lombok中@Builder和@SuperBuilder注解的用法案例
作者:Twilight's Blog
Lombok中@Builder和@SuperBuilder注解的用法
@Builder
是 lombok
中的注解。可以使用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<T> { private T foo; private final String bar; } After: class Example<T> { private T foo; private final String bar; // 私有的全参数构造函数 private Example(T foo, String bar) { this.foo = foo; this.bar = bar; } public static <T> ExampleBuilder<T> builder() { return new ExampleBuilder<T>(); } public static class ExampleBuilder<T> { 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<String> skills
,会添加3个方法:
skill(String skill)
添加单个元素skills(List<String> skillList)
添加一个集合clearSkills()
清空集合,并且将未初始化的集合初始化未空集合。
如果无法计算得到变量名称的奇数形式,则会提示报错信息。用户可以手动指定单数形式的方法名:
@Singular("skill") private List<String> skillList;
这时会生成skill(String skill)
、 skillList(List<String> 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<String> skillList; }
@SuperBuilder(toBuilder=true)
使用 @SuperBuilder(toBuilder=true)
可以使用已有的对象构建新的对象,旧对象的属性值会被保留和覆盖。注意: 子类和父类都需要加上toBuilder=true
Male man = Male.builder() .name("张三") .age(20) .build(); Male man2 = man.toBuilder() .age(30) .build();
PS:java Lombok下解决@Builder继承解决方法(@SuperBuilder)
由于Lombok @Builder不适用于继承用例:
class Foo{ protected int xyz1; ..... protected String xyz7; } class Bar extends Foo{ }
对于给定的用例,Lombok将无法生成方法来设置Foo类中定义的参数值。
解决方法是:
- 手动创建Bar的构造函数。
- 在该构造函数上放置一个Builder注释。
Lombok引入了实验性功能,其版本为:1.18.2,用于解决Builder注释所面临的继承问题,并且可以使用@SuperBuilder注释解决如下。
@SuperBuilder public class ParentClass { private final String a; private final String b; } @SuperBuilder public class ChildClass extends ParentClass{ private final String c; }
现在,可以使用如下所示的Builder类(使用@Builder注解是不可能的)
ChildClass.builder().a("testA").b("testB").c("testC").build();
到此这篇关于Lombok中@Builder和@SuperBuilder注解的用法的文章就介绍到这了,更多相关Lombok中@Builder和@SuperBuilder注解内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!