programing

롬복의 슈퍼 컨스트럭터에 전화하는 방법

goodsources 2022. 11. 1. 00:03
반응형

롬복의 슈퍼 컨스트럭터에 전화하는 방법

수업이 있다

@Value
@NonFinal
public class A {
    int x;
    int y;
}

나는 또 다른 B클래스가 있다.

@Value
public class B extends A {
    int z;
}

lombok이 A() 컨스트럭터를 찾을 수 없다는 오류를 발생시키고 있습니다.명시적으로 lombok이라고 부르는 것은 클래스 b에 주석을 달아 다음 코드를 생성하는 것입니다.

public class B extends A {
    int z;
    public B( int x, int y, int z) {
        super( x , y );
        this.z = z;
    }
}

롬복에서 그렇게 할 수 있는 주석이 있나요?

이것은 롬복에서는 불가능하다.정말 좋은 기능이지만 슈퍼클래스의 컨스트럭터를 찾으려면 해상도가 필요합니다.슈퍼클래스는 롬복이 호출되는 순간에만 이름이 알려진다.Import문과 클래스 경로를 사용하여 실제 클래스를 찾는 것은 간단한 일이 아닙니다.컴파일 중에 리플렉션만 사용하여 생성자 목록을 얻을 수 없습니다.

완전히 불가능한 것은 아니지만, 의 해상도를 사용한 결과입니다.val그리고.@ExtensionMethod그것이 어렵고 오류가 발생하기 쉽다는 것을 알게 되었습니다.

공개:저는 롬복 개발자입니다.

Lombok Issue #78은 이 페이지 https://www.donneo.de/2015/09/16/lomboks-builder-annotation-and-inheritance/을 참조하여 다음과 같은 멋진 설명을 제공합니다.

@AllArgsConstructor 
public class Parent {   
     private String a; 
}

public class Child extends Parent {
  private String b;

  @Builder
  public Child(String a, String b){
    super(a);
    this.b = b;   
  } 
} 

그 결과 생성된 빌더를 다음과 같이 사용할 수 있습니다.

Child.builder().a("testA").b("testB").build(); 

공식 문서에서는 이에 대해 설명하지만, 이러한 방식으로 작업을 수행할 수 있다고 명시적으로 지적하지는 않습니다.

Spring Data JPA에서도 잘 작동한다는 것을 알게 되었습니다.

Lombok 버전 1.18에서는 @SuperBuilder 주석이 도입되었습니다.우리는 이것을 사용하여 보다 간단한 방법으로 문제를 해결할 수 있다.

https://www.baeldung.com/lombok-builder-inheritance#lombok-builder-and-inheritance-3 를 참조해 주세요.

따라서 자녀 클래스에는 다음과 같은 주석이 필요합니다.

@Data
@SuperBuilder
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true)

부모 클래스:

@Data
@SuperBuilder
@NoArgsConstructor

Lombok은 또한 any를 만드는 것으로 나타나는 것을 지원하지 않습니다.@Value주석 클래스final(알고 있듯이)@NonFinal).

제가 찾은 유일한 회피책은 모든 멤버가 직접 최종 결정을 내리고@Data대신 주석을 달 수 있습니다.이러한 서브클래스에 주석을 붙일 필요가 있습니다.@EqualsAndHashCode또한 롬복에서는 슈퍼 클래스의 all args를 사용하여 all args를 작성하는 방법을 모르기 때문에 명시적인 all args 컨스트럭터가 필요합니다.

@Data
public class A {
    private final int x;
    private final int y;
}

@Data
@EqualsAndHashCode(callSuper = true)
public class B extends A {
    private final int z;

    public B(int x, int y, int z) {
        super(x, y);
        this.z = z;
    }
}

특히 서브클래스의 컨스트럭터는 멤버가 많은 슈퍼클래스에 대해서는 솔루션을 약간 어수선하게 만들고 있습니다.죄송합니다.

멤버가 많은 슈퍼클래스는 @Delegate를 사용하는 것이 좋습니다.

@Data
public class A {
    @Delegate public class AInner{
        private final int x;
        private final int y;
    }
}

@Data
@EqualsAndHashCode(callSuper = true)
public class B extends A {
    private final int z;

    public B(A.AInner a, int z) {
        super(a);
        this.z = z;
    }
}

부모보다 자녀 클래스에 구성원이 더 많은 경우 매우 깨끗하지 않고 짧은 방법으로 수행할 수 있습니다.

@Data
@RequiredArgsConstructor
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class User extends BaseEntity {
    private @NonNull String fullName;
    private @NonNull String email;
    ... 

    public User(Integer id, String fullName, String email, ....) {
        this(fullName, email, ....);
        this.id = id;
    }
}

@Data
@AllArgsConstructor
abstract public class BaseEntity {
   protected Integer id;

   public boolean isNew() {
      return id == null;
   }
}

으로 「」를 사용할 수 .com.fasterxml.jackson.databind.ObjectMapper로부터

public class A {
    int x;
    int y;
}

public class B extends A {
    int z;
}

ObjectMapper MAPPER = new ObjectMapper(); //it's configurable
MAPPER.configure( DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false );
MAPPER.configure( SerializationFeature.FAIL_ON_EMPTY_BEANS, false );

//Then wherever you need to initialize child from parent:
A parent = new A(x, y);
B child = MAPPER.convertValue( parent, B.class);
child.setZ(z);

아무 나 쓸 수 요.lombokA는 B로 하겠습니다.

언급URL : https://stackoverflow.com/questions/29740078/how-to-call-super-constructor-in-lombok

반응형