programing

다른 클래스를 확장하는 클래스의 Lombok @builder

css3 2023. 8. 18. 22:50

다른 클래스를 확장하는 클래스의 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();

하지만 지금까지 코드 코멘트 안에 언급된 오류를 이해하고 있습니다.롬복이나 다른 유사한 라이브러리로 어떻게 달성할 수 있는지 올바른 방향을 알려줄 수 있는 사람이 있습니까?

하위 질문

왜 그럴까요?@AllArgsConstructor(onConstructor=@__(@Autowired))편집을 하지만@AllArgsConstructor(onConstructor=@__(@Builder))그렇지 않나요?

릴리스 1.18.2 이후의 lombok에는 새로운 실험이 포함되어 있습니다.슈퍼클래스(추상 클래스)의 필드를 지원합니다.이를 통해 솔루션은 다음과 같이 간단합니다.

@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를 사용하는 경우 사용하려면 IntelliJ Lombok 플러그인의 버전 0.27 이상이 필요합니다.@SuperBuilder.

PS:@AllArgsConstructor(onConstructor=@__(@Builder))다음과 같은 이유로 작동하지 않습니다.@Builder컴파일 중에 lombok이 코드로 변환하는 주석 처리 주석입니다.새로운 롬복 주석을 생성한 다음 번역하려면 주석 처리를 여러 번 반복해야 하며, 롬복은 이를 지원하지 않습니다.@Autowired이와 대조적으로 는 런타임에 사용할 수 있는 일반 Java 주석입니다.

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

올바르게 작동합니다.

사용해야 합니다.@SuperBuilder(toBuilder = true)모든 사물에

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

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

저는 비슷하지만 약간 다른 사용 사례가 있습니다.저의 경우, 요청을 작성하고 실행하는 추상 슈퍼 클래스 체인이 있습니다.서로 다른 요청은 일부 공통 매개 변수를 공유하지만 모든 요청이 모든 매개 변수를 지원하는 것은 아닙니다.구체적인 요청에 대한 작성자는 지정된 요청에 대해 지원되는 매개 변수를 설정하는 방법만 제공해야 합니다.

생성자 기반 빌더 구현으로 시작했지만, 특히 구성해야 할 필드가 많은 경우 너무 많은 상용어구 코드가 발생했습니다.저는 이제 다음과 같은 해결책을 생각해 냈는데, 이것은 제가 보기에 훨씬 더 깨끗해 보입니다.

기본적으로 콘크리트 하위 클래스는 Builder가 지원해야 하는 실제 필드를 정의하고 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();
    }
}

부모가 이미 Builder 메서드를 가지고 있을 때 자식 클래스에 Builder 메서드를 사용하려면 자식 클래스에 대한 모든 변수 생성자를 만든 다음 자식 클래스의 생성자에 주석을 추가하고 속성을 설정할 수 있습니다.

@Builder(builderMethodName = "사용자 지정 buildername")

그런 다음 하위 클래스 Object를 만드는 동안 사용자 지정 이름 작성기를 호출합니다.

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;
}

언급URL : https://stackoverflow.com/questions/44948858/lombok-builder-on-a-class-that-extends-another-class