Lombok @builder在一个扩展另一个类的类上

我有两个类Child扩展Parent 。 我需要在类上放置@Builder注释,这样我就不需要自己创建构建器了。

 package jerry;// Internal compiler error: java.lang.NullPointerException import lombok.AllArgsConstructor; import lombok.Builder; @AllArgsConstructor(onConstructor=@__(@Builder)) public class Child extends Parent { //Multiple markers at this line // - Implicit super constructor Parent() is undefined. Must explicitly invoke another constructor // - overrides java.lang.Object.toString private String a; private int b; private boolean c; } @Builder public class Parent { private double d; private float e; } 

我需要能够构建这样的子实例

 Child child = Child.builder().a("aVal").b(1000).c(true).d(10.1).e(20.0F).build(); 

但到目前为止,我收到了代码注释中提到的错误。 任何人都可以指出我正确的方向如何使用lombok或任何其他类似的库实现它?

子问题

为什么@AllArgsConstructor(onConstructor=@__(@Autowired))编译但@AllArgsConstructor(onConstructor=@__(@Builder))@AllArgsConstructor(onConstructor=@__(@Builder))

请参阅https://blog.codecentric.de/en/2016/05/reducing-boilerplate-code-project-lombok/(@Builder 和inheritance部分)

调整到你的课程

 @AllArgsConstructor public class Parent { private double d; private float e; } public class Child extends Parent { private String a; private int b; private boolean c; @Builder public Child(String a, int b, boolean c, double d, float e) { super(d, e); this.a = a; this.b = b; this.c = c; } } 

有了这个设置

 Child child = Child.builder().a("aVal").b(1000).c(true).d(10.1).e(20.0F).build(); 

工作正常

最新的lombok版本1.18.2包括新的实验性@SuperBuilder 。 它支持超类(也是抽象类)的字段。 有了它,解决方案就像这样简单:

 @SuperBuilder public class Child extends Parent { private String a; private int b; private boolean c; } @SuperBuilder public class Parent { private double d; private float e; } Child instance = Child.builder().b(7).e(6.3).build(); 

PS: @AllArgsConstructor(onConstructor=@__(@Builder))不起作用,因为@Builder是一个注释处理注释, @Builder在编译期间转换为代码。 生成并翻译新的lombok注释需要多次迭代注释处理,而lombok不支持。 相比之下,@ @Autowired是运行时可用的常规Java注释。

我有一个类似但略有不同的用例。 在我的例子中,我有一系列构建和执行请求的抽象超类。 不同的请求共享一些公共参数,但并非每个请求都支持所有参数。 具体请求的构建器应仅提供为给定请求设置支持的参数的方法。

我开始使用基于构造函数的构建器实现,但这导致了太多样板代码,特别是如果要配置许多字段。 我现在想出了以下解决方案,对我来说看起来更干净。

基本上,具体的子类定义了Builder应该支持的实际字段,而Getter注释会导致相应的超类方法被覆盖。 抽象超类中的getter甚至可以定义为抽象,以要求具体实现来定义这些字段。

 public abstract class AbstractSuperClass1 { protected String getParamA() { return "defaultValueA"; } public final void doSomething() { System.out.println(getParamA()); doSomeThingElse(); } protected abstract void doSomeThingElse(); } 

 public abstract class AbstractSuperClass2 extends AbstractSuperClass1 { protected String getParamB() { return "defaultValueB"; } protected void doSomeThingElse() { System.out.println(getParamB()); } } 

 import lombok.AccessLevel; import lombok.Builder; import lombok.Getter; @Getter(AccessLevel.PROTECTED) @Builder public class ConcreteClass1 extends AbstractSuperClass2 { private final String paramA; // Not supported by this implementation: private final String paramB; public static void main(String[] args) { ConcreteClass1.builder() .paramA("NonDefaultValueA") .build().doSomething(); } } 

 import lombok.AccessLevel; import lombok.Builder; import lombok.Getter; @Getter(AccessLevel.PROTECTED) @Builder public class ConcreteClass2 extends AbstractSuperClass2 { private final String paramA; private final String paramB; public static void main(String[] args) { ConcreteClass2.builder() .paramA("NonDefaultValueA").paramB("NonDefaultValueB") .build().doSomething(); } }