Lombokのコンストラクタ生成に関する以下アノテーションの利用サンプルです。
@NoArgsConstructor
(lombok.NoArgsConstructor)@AllArgsConstructor
(lombok.AllArgsConstructor)@RequiredArgsConstructor
(lombok.RequiredArgsConstructor)
デフォルトコンストラクタを生成する
@NoArgsConstructor
をクラスに付与することでデフォルトコンストラクタを自動生成することができます。
■@NoArgsConstructorを付与したクラス
import lombok.NoArgsConstructor; @NoArgsConstructor public class Person1 { private long id; private String name; private int age; }
■実際に生成されるソースコード
実際に生成されているソースコードは以下です(delombokで確認)
デフォルトコンストラクタが生成されていることが分かります。
public class Person1 { private long id; private String name; private int age; public Person1() { } }
全メンバをセットするためのコンストラクタを生成する
@AllArgsConstructor
をクラスに付与することで全メンバへ値をセットするための引数付きコンストラクタを自動生成することができます。
■@AllArgsConstructorを付与したクラス
import lombok.AllArgsConstructor; @AllArgsConstructor public class Person2 { private long id; private String name; private int age; }
■実際に生成されるソースコード
実際に生成されているソースコードは以下です(delombokで確認)
全メンバをセットするための引数付きコンストラクタが生成されていることが分かります。
public class Person2 { private long id; private String name; private int age; public Person2(final long id, final String name, final int age) { this.id = id; this.name = name; this.age = age; } }
@NoArgsConstructor + @AllArgsConstructor
@NoArgsConstructor
と@AllArgsConstructor
をクラスに付与することでデフォルトコンストラクタと全メンバへ値をセットするための引数付きコンストラクタの両方を自動生成することができます。
■@NoArgsConstructorと@AllArgsConstructorを付与したクラス
import lombok.AllArgsConstructor; import lombok.NoArgsConstructor; @NoArgsConstructor @AllArgsConstructor public class Person3 { private long id; private String name; private int age; }
■実際に生成されるソースコード
実際に生成されているソースコードは以下です(delombokで確認)
デフォルトコンストラクタと全メンバをセットするための引数付きコンストラクタが生成されていることが分かります。
public class Person3 { private long id; private String name; private int age; public Person3() { } public Person3(final long id, final String name, final int age) { this.id = id; this.name = name; this.age = age; } }
必須のメンバへ値をセットするコンストラクタを生成する
@RequiredArgsConstructor
をクラスに付与することで必須のメンバ(finalのメンバ)へ値をセットするための引数付きコンストラクタを自動生成することができます。
■@RequiredArgsConstructorを付与したクラス
import lombok.RequiredArgsConstructor; @RequiredArgsConstructor public class Person4 { private final long id; private String name; private int age; }
■実際に生成されるソースコード
実際に生成されているソースコードは以下です(delombokで確認)
finalのメンバ(id)へ値をセットするためのコンストラクタが生成されています。
public class Person4 { private final long id; private String name; private int age; public Person4(final long id) { this.id = id; } }
@RequiredArgsConstructor + @AllArgsConstructor
@RequiredArgsConstructor
と@AllArgsConstructor
をクラスに付与することで必須メンバへ値をセットするためのコンストラクタと全メンバへ値をセットするためのコンストラクタの両方を自動生成することができます。
■@RequiredArgsConstructorと@AllArgsConstructorを付与したクラス
import lombok.AllArgsConstructor; import lombok.RequiredArgsConstructor; @RequiredArgsConstructor @AllArgsConstructor public class Person5 { private final long id; private String name; private int age; }
■実際に生成されるソースコード
実際に生成されているソースコードは以下です(delombokで確認)
必須メンバへ値をセットするコンストラクタと全メンバをセットするためのコンストラクタが生成されていることが分かります。
public class Person5 { private final long id; private String name; private int age; public Person5(final long id) { this.id = id; } public Person5(final long id, final String name, final int age) { this.id = id; this.name = name; this.age = age; } }
コンストラクタのアクセスレベルを制御する
コンストラクタを生成するためのアノテーションを使用した場合、デフォルトではコンストラクタのアクセスレベルはpublicになります。
このアクセスレベルを制御したい場合は、access
パラメータを使用します。
■サンプルコード
import lombok.AccessLevel; import lombok.NoArgsConstructor; import lombok.RequiredArgsConstructor; public class Person6 { @NoArgsConstructor(access=AccessLevel.PRIVATE) public static class Person6a { private long id; private String name; private int age; } @RequiredArgsConstructor(access=AccessLevel.PROTECTED) public static class Person6b { private final long id; private String name; private int age; } }
■実際に生成されるソースコード
実際に生成されているソースコードは以下です(delombokで確認)
Person6aのコンストラクタのアクセスレベルがprivateに、Person6bのコンストラクタのアクセスレベルがprotectedになっていることが分かります。
public class Person6 { public static class Person6a { private long id; private String name; private int age; private Person6a() { } } public static class Person6b { private final long id; private String name; private int age; protected Person6b(final long id) { this.id = id; } } }
ファクトリメソッドを定義する
コンストラクタを直接呼ばせずにファクトリメソッドを呼ばせるようにしたい場合があります。
そのような場合は、staticName
パラメータを使用することで、ファクトリメソッドを定義できます。
■サンプルコード
import lombok.AllArgsConstructor; import lombok.NoArgsConstructor; import lombok.RequiredArgsConstructor; public class Person7 { @RequiredArgsConstructor(staticName="of") public static class Person7a { private final long id; private String name; private int age; } @NoArgsConstructor(staticName="create") @AllArgsConstructor(staticName="create") public static class Person7b { private long id; private String name; private int age; } }
■実際に生成されるソースコード
実際に生成されているソースコードは以下です(delombokで確認)
staticName
で指定した名前のファクトリメソッドが定義されていることが分かります。また、コンストラクタはprivateになっていることも分かります。
public class Person7 { public static class Person7a { private final long id; private String name; private int age; private Person7a(final long id) { this.id = id; } public static Person7a of(final long id) { return new Person7a(id); } } public static class Person7b { private long id; private String name; private int age; private Person7b() { } public static Person7b create() { return new Person7b(); } private Person7b(final long id, final String name, final int age) { this.id = id; this.name = name; this.age = age; } public static Person7b create(final long id, final String name, final int age) { return new Person7b(id, name, age); } } }
@NonNullと組み合わせる
必須メンバ(finalのメンバ)が存在するクラスに、@RequiredArgsConstructor
や@AllArgsConstructor
を付与しただけだと、対象メンバにnullをセットすることが許容されてしまいます。
メンバがnullになることが許容できない場合は、@NonNull
アノテーションを組み合わせましょう。
■サンプルコード
import lombok.AllArgsConstructor; import lombok.NonNull; import lombok.RequiredArgsConstructor; public class Person8 { @RequiredArgsConstructor public static class Person8a { private long id; @NonNull private final String name; private int age; } @AllArgsConstructor public static class Person8b { private final long id; @NonNull private final String name; @NonNull private final String description; } }
■実際に生成されるソースコード
実際に生成されているソースコードは以下です(delombokで確認)
コンストラクタの処理内でnullがガードされていることが分かります。
import lombok.NonNull; public class Person8 { public static class Person8a { private long id; @NonNull private final String name; private int age; public Person8a(@NonNull final String name) { if (name == null) { throw new NullPointerException("name"); } this.name = name; } } public static class Person8b { private final long id; @NonNull private final String name; @NonNull private final String description; public Person8b(final long id, @NonNull final String name, @NonNull final String description) { if (name == null) { throw new NullPointerException("name"); } if (description == null) { throw new NullPointerException("description"); } this.id = id; this.name = name; this.description = description; } } }
コンストラクタにアノテーションを付与する
DIコンテナを使用していて、コンストラクタインジェクションをやりたい場合などに、コンストラクタに@Inject
アノテーションを付与します。
このように、コンストラクタへ何らかのアノテーションを付与したい場合は、onConstructor
パラメータを利用します。
パラメータは以下のように記述します。
onConstructor=@__({付与したいアノテーション})
■サンプルコード
onConstructor
パラメータで、@Inject
アノテーションを付与するように指定しています。
import javax.inject.Inject; import lombok.AllArgsConstructor; import lombok.RequiredArgsConstructor; public class Person9 { @RequiredArgsConstructor(onConstructor=@__({@Inject})) public static class Person9a { private long id; private final String name; private int age; } @AllArgsConstructor(onConstructor=@__({@Inject})) public static class Person9b { private final long id; private final String name; private int age; } }
■実際に生成されるソースコード
実際に生成されているソースコードは以下です(delombokで確認)
コンストラクタに@Inject
アノテーションが付与されていることが分かります。
import javax.inject.Inject; public class Person9 { public static class Person9a { private long id; private final String name; private int age; @Inject public Person9a(final String name) { this.name = name; } } public static class Person9b { private final long id; private final String name; private int age; @Inject public Person9b(final long id, final String name, final int age) { this.id = id; this.name = name; this.age = age; } } }