@SuperBuilder的用法
@SuperBuilder
是 Lombok 提供的一个注解,用于生成一个具有父类和子类构建器的构建器模式。它可以让你更方便地创建复杂对象,尤其是在继承层次结构中。下面是一个简单的例子来展示它的用法:
示例代码
假设我们有一个父类 Parent
和一个子类 Child
:
import lombok.Getter;
import lombok.experimental.SuperBuilder;
@Getter
@SuperBuilder
public class Parent {
private final String parentField;
}
@Getter
@SuperBuilder
public class Child extends Parent {
private final String childField;
}
使用构建器创建对象
你可以使用生成的构建器来创建 Parent
和 Child
对象:
public class Main {
public static void main(String[] args) {
Parent parent = Parent.builder()
.parentField("Parent Field Value")
.build();
Child child = Child.builder()
.parentField("Parent Field Value")
.childField("Child Field Value")
.build();
System.out.println("Parent Field: " + parent.getParentField());
System.out.println("Child Parent Field: " + child.getParentField());
System.out.println("Child Field: " + child.getChildField());
}
}
解释
- 注解:
@SuperBuilder
注解用于生成构建器模式的代码。 - 父类构建器:
Parent.builder()
用于创建Parent
对象。 - 子类构建器:
Child.builder()
用于创建Child
对象,并且可以设置父类和子类的字段。
注意事项
- 不可变对象:
@SuperBuilder
通常用于创建不可变对象,因为它会生成final
字段。 - 继承:
@SuperBuilder
支持继承关系,可以在子类中设置父类的字段。
通过使用 @SuperBuilder
,你可以简化复杂对象的创建过程,尤其是在有继承关系的情况下。
为什么final字段不需要赋初始值
在 Java 中,final
字段必须在对象构造完成之前被赋值。通常有以下几种方式来赋值 final
字段:
-
在声明时赋值:
private final String parentField = "default value";
-
在构造函数中赋值:
public Parent(String parentField) { this.parentField = parentField; }
-
在初始化块中赋值:
{ parentField = "default value"; }
在使用 Lombok 的 @SuperBuilder
注解时,Lombok 会自动生成一个构造函数,并在构造函数中为 final
字段赋值。因此,你不需要显式地在代码中为 final
字段赋值。Lombok 会确保在对象构造完成之前,所有的 final
字段都已经被正确赋值。
生成的代码示例
假设我们有以下类:
@Getter
@SuperBuilder
public class Parent {
private final String parentField;
}
Lombok 会生成类似于以下的代码:
public class Parent {
private final String parentField;
private Parent(ParentBuilder<?, ?> b) {
this.parentField = b.parentField;
}
public static ParentBuilder<?, ?> builder() {
return new ParentBuilderImpl();
}
public static abstract class ParentBuilder<C extends Parent, B extends ParentBuilder<C, B>> {
private String parentField;
public B parentField(String parentField) {
this.parentField = parentField;
return self();
}
protected abstract B self();
public abstract C build();
}
private static final class ParentBuilderImpl extends ParentBuilder<Parent, ParentBuilderImpl> {
@Override
protected ParentBuilderImpl self() {
return this;
}
@Override
public Parent build() {
return new Parent(this);
}
}
}
在这个生成的代码中,ParentBuilder
类负责构建 Parent
对象,并在构造函数中为 final
字段 parentField
赋值。因此,当你使用 Parent.builder().parentField("value").build()
时,Lombok 会确保 parentField
在构造函数中被正确赋值。
总结
Lombok 的 @SuperBuilder
注解会自动生成构造函数,并在构造函数中为 final
字段赋值,因此你不需要显式地在代码中为 final
字段赋值。这是 Lombok 提供的便利之一,使得代码更加简洁和易于维护。