我可以使用 Lombok @Builder 传递父类作为参数吗?

fre*_*dev 8 java lombok

我想创建一个Child传递 aParent和其他附加参数的新实例。

例如,如果我有:

public class Parent {
    public String param1;
    public String param2;
    // many parameters
    public String paramN;
}

public class Child extends Parent {
    public String subValue;
}
Run Code Online (Sandbox Code Playgroud)

使用 lombok,是否有一个构建器可以让我创建一个ChildParent和缺失值作为参数传递的实例?

如果我可以写一些类似的东西会更容易:

Parent p = Parent.builder()
                 .param1("a")
                 .param2("b")
                 // many parameters
                 .paramN("b")
                 .build();
Child c = Child.builder(p).subValue("c").build();
Run Code Online (Sandbox Code Playgroud)

Jan*_*eke 6

常规方法@Builder在这里是不够的,因为您正在处理类层次结构。然而,@SuperBuilder正是针对这种情况而设计的。

@SuperBuilder生成加载泛型的复杂代码。如果没有深入了解@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);
    }
}
Run Code Online (Sandbox Code Playgroud)

newtoBuilder方法Child创建一个新的(调用时ChildBuilderImpl会创建一个实例)。为了填充给定的值,它调用from 的新方法。此方法进一步将调用委托给由 Lombok 生成的方法,并执行将字段值实际复制到新构建器实例的操作。Childbuild()Parent p$fillValuesFromParentParentBuilder$fillValuesFromInstanceIntoBuilder

另请注意$方法上的前缀。这基本上是说:我是一个实现细节;除非您知道自己在做什么,否则不要使用我,我可能会在下一个 Lombok 版本上中断,恕不另行通知。


Evd*_*afa 2

其他答案并不能真正使您的客户端代码简单地重用您已有的父实例。但这是可行的。您有两个选择:

困难的是编写满足您需求的自定义注释。您甚至可以使其通用,以便它适用于具有父/子层次结构的任何类。看看这个例子。如果您有勇气,可以在Lombok 的 github页面上提出功能请求。

选项二是为孩子编写自定义构建器。请参阅此处的示例。在初始化步骤中的自定义构建器中,您将读取传入的父实例,并仅设置继承的字段。