[英]Can I use both @data and @builder annotations in one class Lombok?
[英]Can I use the Lombok @Builder passing the parent class as parameter?
我想创建一个传递Parent
和其他附加参数的新Child
实例。
例如,如果我有:
public class Parent {
public String param1;
public String param2;
// many parameters
public String paramN;
}
public class Child extends Parent {
public String subValue;
}
使用 lombok,是否有一个构建器可以让我创建一个Child
实例,将Parent
和缺失值作为参数传递?
如果我能写这样的东西会更容易:
Parent p = Parent.builder()
.param1("a")
.param2("b")
// many parameters
.paramN("b")
.build();
Child c = Child.builder(p).subValue("c").build();
其他答案并不能真正使您的客户端代码简单地重用您已经拥有的父实例。 但这是可行的。 你有两个选择:
困难的是编写您想要的自定义注释。 您甚至可以使其通用,以便它适用于具有父/子层次结构的任何类。 看看这个例子。 如果您觉得勇敢,可以在Lombok 的 github页面上提出功能请求。
选项二是为孩子编写自定义构建器。 请参见此处的示例。 在初始化步骤中的自定义构建器中,您将读取传入的 Parent 实例,并仅设置继承的字段。
常规的@Builder
在这里是不够的,因为您正在处理 class 层次结构。 但是, @SuperBuilder
正是针对这种情况而设计的。
@SuperBuilder
生成加载了 generics 的复杂代码。 如果没有深入了解@SuperBuilder
生成的代码,这使得该解决方案难以理解。 你应该考虑一下这是否值得。
这是解决方案(Lombok >= 1.18.16):
@SuperBuilder(toBuilder = true)
public static class Parent {
public String param1;
public String param2;
// many parameters
public String paramN;
public abstract static class ParentBuilder<C extends Parent, B extends Parent.ParentBuilder<C, B>> {
protected B $fillValuesFromParent(Parent instance) {
$fillValuesFromInstanceIntoBuilder(instance, this);
return self();
}
}
}
@SuperBuilder(toBuilder = true)
public static class Child extends Parent {
public String subValue;
public static ChildBuilder<?, ?> toBuilder(Parent p) {
return new ChildBuilderImpl().$fillValuesFromParent(p);
}
}
Child
上的新toBuilder
方法创建一个新的ChildBuilderImpl
(它将在调用build()
时创建一个Child
实例)。 为了填充给定Parent p
的值,它从ParentBuilder
调用新的$fillValuesFromParent
方法。 此方法进一步将调用委托给方法$fillValuesFromInstanceIntoBuilder
,该方法由 Lombok 生成,并将字段值实际复制到新的构建器实例。
还要注意方法上的$
前缀。 这基本上是说:我是一个实现细节; 除非您知道自己在做什么,否则不要使用我,我可能会在下一个 Lombok 版本上中断,恕不另行通知。
我建议你使用@SuperBuilder
@SuperBuilder 作为 lombok v1.18.2 中的实验功能引入。 @SuperBuilder 注释为您的类生成复杂的构建器 API。 与@Builder 相比,@SuperBuilder 也适用于来自超类的字段。 但是,它仅适用于类型。 最重要的是,它要求所有超类也有 @SuperBuilder 注释。
@Getter
@SuperBuilder
public class Parent {
public String name;
public String value;
}
@Getter
@SuperBuilder
public class Child extends Parent {
public String subValue;
}
那么你需要做的就是
Child.builder().name("a").value("b").subValue("c").build();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.