나는 수업이있다
@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;
}
}
롬복에서 할 수있는 주석이 있습니까?
답변
롬복에서는 불가능합니다. 정말 멋진 기능이기는하지만 슈퍼 클래스의 생성자를 찾으려면 해결해야합니다. 수퍼 클래스는 Lombok이 호출되는 순간 이름으로 만 알려져 있습니다. 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();
공식 문서는 이 설명하지만, 명시 적으로이 방법을 용이하게 할 수 있음을 지적하지 않습니다.
나는 또한 이것이 SpringData JPA와 잘 작동한다는 것을 알았습니다.
답변
Lombok은 @Value
주석이 달린 클래스 final
(를 사용하여 알고 있음)를 작성하여 표시하는 것도 지원하지 않습니다 @NonFinal
.
내가 찾은 유일한 해결 방법은 모든 구성원을 최종적으로 선언하고 @Data
대신 주석을 사용하는 것입니다. @EqualsAndHashCode
Lombok은 수퍼 클래스 중 하나 인 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;
}
}
답변
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
답변
옵션 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);
lombok
필요한 경우 A와 B에 대한 주석을 계속 사용할 수 있습니다 .
