クラスがあります
@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でそれを行うための注釈はありますか?
これはロンボク島では不可能です。これは本当に素晴らしい機能ですが、スーパークラスのコンストラクターを見つけるには解決が必要です。スーパークラスは、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();
公式ドキュメント はこれを説明していますが、この方法でそれを促進できることを明示的に指摘していません。
また、Spring Data 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;
}
}