なんの話か
言いたいことはほぼタイトルに書いてしまいました。
本記事で言いたいことは以下だけです。
Lombok1.16.18での挙動となります。
- Lombokの@Valueや@Dataは他に明示的なコンストラクタが宣言されているとコンストラクタを生成しない(そういう仕様である)
- @NoArgsConstructorなどと併用した場合も同様
- @Valueと@Dataを両方つけると@AllArgsConstructorが勝つ(Setterも生成される)
通常の使い方
import lombok.*;
@Data
public class Test {
private final int value1;
private final int value2;
public static void main(String[] args){
new Test(1, 1);
}
}
この場合@Dataが@RequiredArgsConstructorをバンドルしているため、コンストラクタが生成されコンパイルが通ります。
コンストラクタが生成されないケース
しかし、このバンドルされた@RequiredArgsConstructorによるコンストラクタの生成は、明示的なコンストラクタの宣言がない場合にのみ行われます。
これはドキュメントにも記載されている正常な動作です。
(except that no constructor will be generated if any explicitly written constructors already exist).
@Dataより引用
例(明示的なコンストラクタの宣言)
例えば、以下のコードはコンパイルが通りません。
import lombok.*;
@Data
public class Test {
private final int value1;
private final int value2;
public static void main(String[] args){
new Test(1, 1);
}
// 明示的なコンストラクタ
public Test() {
}
}
例(アノテーションによるコンストラクタの生成)
@NoArgsConstructorなどのコンストラクタを生成するアノテーションをつけた場合も、同様に@Dataによるコンストラクタの生成が行われません。
よって、以下のコードはコンパイルが通りません。
import lombok.*;
@NoArgsConstructor
@Data
public class Test {
private final int value1;
private final int value2;
public static void main(String[] args){
new Test(1, 1);
}
}
@Dataと@Valueを両方ともつけると@AllArgsConstructorが勝つようです。
import lombok.*;
import java.util.Arrays;
@Data
@Value
public class Test {
int value1;
int value2;
public static void main(String[] args){
Arrays.stream(Test.class.getConstructors()).forEach(System.out::println);
new Test(1, 1); // これは通る
new Test(); // これは通らない
}
}
一応明示的なコンストラクタ+@Data+@Valueも試しましたが、いずれのコンストラクタも生成されませんでした。
import lombok.*;
import java.util.Arrays;
@Value
@Data
public class Test {
int value1;
int value2;
public static void main(String[] args){
Arrays.stream(Test.class.getConstructors()).forEach(System.out::println);
}
// 明示的なコンストラクタ
public Test(int i){
}
}