Lombokで提供するコンストラクタのアノテーション探求

## Lombokで提供する3つのコンストラクタ

- Lombokでボイラープレートコードを減らすために提供する3つのコンストラクタ関連のアノテーションについて知ろう
> ボイラープレートコードとは？ (Boiler Plate)
-  ほとんどまたは全く変更せずに、様々な場所で繰り返されるコード
[ウィキペディア ボイラープレートコード](https://en.wikipedia.org/wiki/Boilerplate_code)


---

### @ RequiredArgsConstructor

```java/**
 * Generates a constructor with required arguments.
 * Required arguments are final fields and fields with constraints such as {@code @NonNull}.
 * <p>
 * Complete documentation is found at <a href="https://projectlombok.org/features/constructor">the project lombok features page for &#64;Constructor</a>.
 * <p>
 * Even though it is not listed, this annotation also has the {@code onConstructor} parameter. See the full documentation for more details.
 * 
 * @see NoArgsConstructor
 * @see AllArgsConstructor
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface RequiredArgsConstructor 
```

- 必須の引数を使ってコンストラクタを作ると言います

- ここでの必須の引数は、finalが付いたフィールドと、@NonNullのような制約条件があるフィールドです


```java
@RequiredArgsConstructor
public class AclassTest {

    private final String usedFinal;
    private String notUsedFinal;

    @NotNull
    private String usedNotNull;
}
```
このように3つのケースを考慮してテストをしてみるならば

![image (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3815412/58601a71-5a57-c851-0dd5-ed2a7b307a6b.png)

- 上記のように、finalが付いたフィールドのみが生成されることがわかります
（上の写真はデコンパイルされた .class ファイルです）

- この原理を利用すれば、Spring 4.3から提供されている一つのコンストラクタを定義するだけで、そのコンストラクタの @Autowired を省略できることを利用し、コードの長さとメンテナンスにかかる時間を削減し、DIを使用することができます
---
### @ NoArgsConstructor
```java
/**
 * Generates a no-args constructor.
 * Will generate an error message if such a constructor cannot be written due to the existence of final fields.
 * <p>
 * Complete documentation is found at <a href="https://projectlombok.org/features/constructor">the project lombok features page for &#64;Constructor</a>.
 * <p>
 * Even though it is not listed, this annotation also has the {@code onConstructor} parameter. See the full documentation for more details.
 * <p>
 * NB: Fields with constraints such as {@code @NonNull} will <em>NOT</em> be checked in a {@code @NoArgsConstructor} constructor, of course!
 * 
 * @see RequiredArgsConstructor
 * @see AllArgsConstructor
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface NoArgsConstructor
```

- 引数のないコンストラクタを生成します。
- 不変フィールド（final fields）の存在により、そのようなコンストラクタを作成できない場合、エラーメッセージが生成されます

```java
@NoArgsConstructor
public class AclassTest {

    private String a;
    private String b;

    @NotNull
    private String c;

}

```
上記のようなコードを使用する場合

![image (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3815412/49bc9c9f-f4aa-af03-d036-5d06405232ba.png)

- 正しく引数のないコンストラクタを生成します

```java
@NoArgsConstructor
public class AclassTest {

    private final String usedFinal;
    private String notUsedFinal;

    @NotNull
    private String usedNotNull;

}
```

上記の例のように final フィールドを作成するならば!

![image (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3815412/b314c47d-6abf-b5fa-dbbc-bd30ac30b2ff.png)

- 上記のようにコンパイルエラーが発生します

なぜなら、引数のないコンストラクタを生成するときに、final フィールドを初期化できないからです

- これを解決するために,@NoArgsConstructor(force = true)をつかいます

```java
@NoArgsConstructor(force = true)
public class AclassTest {

    private final String usedFinal;
    private String notUsedFinal;

    @NotNull
    private String usedNotNull;

}
```
上記のような方法で解決するならば。

![image (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3815412/f08b3779-2917-b024-56a3-afa6d89e2d18.png)

- Lombokでは適切なデフォルト値を生成し、引数のないコンストラクタを生成します

---

### @ AllArgsConstructor

```java
/**
 * Generates an all-args constructor.
 * An all-args constructor requires one argument for every field in the class.
 * <p>
 * Complete documentation is found at <a href="https://projectlombok.org/features/constructor">the project lombok features page for &#64;Constructor</a>.
 * <p>
 * Even though it is not listed, this annotation also has the {@code onConstructor} parameter. See the full documentation for more details.
 * 
 * @see NoArgsConstructor
 * @see RequiredArgsConstructor
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface AllArgsConstructor 

```

- すべての引数を受け取るコンストラクタを生成します
- すべての引数を受け取るコンストラクタは、クラスのすべてのフィールドに対して1つの引数が必要です

```java
@AllArgsConstructor
public class AclassTest {

    private final String usedFinal;
    private String notUsedFinal;

    @NotNull
    private String usedNotNull;
}

```

上記のようにコードを書くならば？

![image (5).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3815412/d2093ba7-5bb1-f0ee-e86c-b998a937f0cb.png)

上記のように、すべてのフィールドを持つコンストラクタを作成します。

---

## リファレンス

Lombok ドキュメント : [lombok_constructor_docs](https://projectlombok.org/features/constructor)


---



- 저는 한국인으로서 일본어를 공부하기 위해 ChatGPT, Papago, Google 번역을 활용하여 이 문장을 썼습니다

- まだ日本語が未熟なので翻訳ツールを使用したため、文脈が不自然だったりおかしい部分が多いかもしれません

- 指摘していただければ学んでいきます

- 日本人の開発者とコミュニケーションを取りたいです。


技術的なフィードバックもいつでも歓迎します。

ありがとうございます。よい一日をお過ごしください。