hibernate Lombok @builder位于扩展另一个类的类上

hvvq6cgz  于 2022-12-23  发布在  其他
关注(0)|答案(5)|浏览(139)

我有两个类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))不能?

kq0g1dla

kq0g1dla1#

从1.18.2版本开始,lombok就包含了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();
  • 更新2019-10-09:* 如果您使用IntelliJ,您至少需要0.27版本的IntelliJ Lombok插件才能使用@SuperBuilder

PS:@AllArgsConstructor(onConstructor=@__(@Builder))不起作用,因为@Builder是一个注解处理注解,lombok在编译期间将其翻译为代码。生成并翻译新的lombok注解需要多次迭代注解处理,而lombok不支持这种情况。相反,@Autowired是一个在运行时可用的常规Java注解。

ca1c2owp

ca1c2owp2#

请参见https://blog.codecentric.de/en/2016/05/reducing-boilerplate-code-project-lombok/(*@生成器和继承 * 部分)
适应你的课程

@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();

工作正常

h43kikqp

h43kikqp3#

您需要在每个对象中使用@SuperBuilder(toBuilder = true)

@Data
@SuperBuilder(toBuilder = true)
public class Parent extends Child {
}

@Data
@SuperBuilder(toBuilder = true)
public class Child {
}
suzh9iv8

suzh9iv84#

我有一个相似但稍有不同的用例。在我的用例中,我有一个构建和执行请求的抽象超类链。不同的请求共享一些公共参数,但不是每个请求都支持所有参数。具体请求的构建器应该只提供为给定请求设置支持参数的方法。
我从基于构造函数的构建器实现开始,但是这导致了太多的样板代码,特别是当你有很多字段要配置的时候,我现在提出了下面的解决方案,在我看来,这看起来更简洁了。
基本上,具体的子类定义了构建器应该支持的实际字段,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();
    }
}
z4iuyo4d

z4iuyo4d5#

如果你的子类想要一个builder方法,而父类已经有了,那么你可以为子类创建一个allargs构造函数,然后在子类的构造函数上标注builder并设置属性
@生成器(生成器方法名称=“自定义生成器名称”)
然后在创建子类Object时调用customname生成器。

package jerry;

import lombok.AllArgsConstructor;
import lombok.Builder;

public class Child extends Parent { 

   private String a;
   private int b;
   private boolean c;

   @Builder(builderMethodName = "childBuilder")
   public Child(String a, int b, boolean c, double d, float e){
       super(d,e);
   }

}

@Builder
public class Parent {
    private double d;
    private float e;
}

相关问题