我有两个课程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))
没有?
答案 0 :(得分:24)
参见https://blog.codecentric.de/en/2016/05/reducing-boilerplate-code-project-lombok/( @Builder和继承部分)
调整到您的课程
@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();
正常工作
答案 1 :(得分:17)
最新的lombok版本1.18.2包含the new experimental @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
是注解处理注解,在编译过程中lombok会将其转换为代码。生成然后翻译新的lombok批注将需要进行多次批注处理,而lombok不支持该迭代。相反,@Autowired
是运行时可用的常规Java注释。
答案 2 :(得分:1)
我有一个类似但略有不同的用例。在我的例子中,我有一系列构建和执行请求的抽象超类。不同的请求共享一些公共参数,但并非每个请求都支持所有参数。具体请求的构建器应仅提供为给定请求设置支持的参数的方法。
我开始使用基于构造函数的构建器实现,但这导致了太多样板代码,特别是如果要配置许多字段。我现在想出了以下解决方案,对我来说看起来更干净。
基本上,具体的子类定义了Builder应该支持的实际字段,而Getter注释会导致重写相应的超类方法。抽象超类中的getter甚至可以定义为abstract,以要求具体实现来定义这些字段。
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();
}
}
答案 3 :(得分:0)
您需要在每个对象中使用 @SuperBuilder(toBuilder = true)
。
@Data
@SuperBuilder(toBuilder = true)
public class Parent extends Child {
}
@Data
@SuperBuilder(toBuilder = true)
public class Child {
}