Lombokの@Getter @Setterの動作メモ

## はじめに
これはLombokの`@Getter`, `@Setter`に絞って動作検証をした結果のメモとなります。
Lombokの導入の仕方や`@Getter`や`@Setter`以外のアノテーションの使い方は、ここでは書きませんので他の人がまとめてくれているものを見てください。

* [Lombok](https://qiita.com/yyoshikaw/items/32a96332cc12854ca7a3)
* [Lombok 使い方メモ](https://qiita.com/opengl-8080/items/671ffd4bf84fe5e32557)

## Lombokについて
本題に入る前に簡単にLombokの説明を。
Lombokとは特定のアノテーションを利用することで`getter`や`setter`、`toString`などのメソッドを自動で生成してくれるライブラリです。

開発の段階でPOJOオブジェクトなどの記述量を減らすことができます。
今どきgetter、setterを自前で書いている人は少ないかもしれませんが、自動生成のため**スペルミス**を無くせます。

## 実践
それではさっそく使ってみましょう。

### 特定のフィールドに対してgetter、setterを作成したい場合
この場合はgetter、setterを作成したいフィールドに対して`@Getter`、`@Setter`を付与します。

```java:Product.java
import lombok.Getter;
import lombok.Setter;

public class Product {

	@Getter
	@Setter
	private long id;

	@Getter
	private String name = "マウス";
}
```
アウトラインを確認するとフィールドに対して指定したgetter、setterが作成されていることがわかります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232125/1a83e9f1-443e-58d8-b3d3-de56bdb82df8.png)

実際に動くか確認します。

```java
public static void main(String[] args) {
	Product product = new Product();
	product.setId(1L);

	System.out.println(product.getId());
	System.out.println(product.getName());
}
```

```:コンソール
1
マウス
```
このようにそれぞれ正しく動いていることがわかります。

### クラス内にあるフィールドすべてにgetter、setterを作成したい場合
先ほどフィールドに対して`@Getter`や`@Setter`を付与しましたが、この場合はクラスに対して`@Getter`と`@Setter`を付与します。

```java:Product.java
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class Product {

	private long id;

	private String name;
}
```

クラス内にあるフィールドすべてにgetter、setterが作成されていることがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232125/35c3e425-03fb-6e8f-8541-5327c3aff890.png)

動作検証は省略します。

### getterは全フィールドへsetterは一部のフィールドへ作成したい場合
この場合は全フィールドへ適用したいものはクラスへ、一部のフィールドへ適用したいものはフィールドへ、それぞれのアノテーションを付与します。

```java:Product.java
import lombok.Getter;
import lombok.Setter;

@Getter
public class Product {

	@Setter
	private long id;

	private String name;
}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232125/a4253d8c-ee31-1a40-8f59-ccc5d755aeb7.png)

指定した通り`id`にしかsetterは作成されていないですね。

### 一部のフィールドだけgetter、setterを作成したくない場合
クラス内のほぼすべてのフィールドにはgetterとsetterを作成したいけど、一部のフィールドには作成したくない場合は`AccessLevel.NONE`を指定します。
`AccessLevel`では作成されるgetter、setterのアクセス修飾子を変更でき、何も指定しない場合は`public`となります。

```java:Product.java
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class Product {

	@Getter(AccessLevel.NONE)
	private long id;

	@Setter(AccessLevel.NONE)
	private String name;
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232125/76beef33-a68f-ddda-1a88-573dd3459602.png)

このように`AccessLevel.NONE`を指定したgetter、setterが作成されていないことがわかります。


### getter、setterの動作をデフォルトから変えたい場合
開発しているとクラス内の一部だけgetterやsetterの動作を変えたい場合に遭遇します。
その場合には自前で動作を変えたいフィールドのgetter、setterを実装します。
今回は`name`フィールドの`getter`だけ自前で実装してみましょう。

```java:Product.java
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class Product {

	private long id;

	private String name;

	public String getName() {
		return "商品名: " + name;
	}
}
```

アウトラインからは順序が変わりましたが、`getter`があることは分かります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232125/77dbeeee-afaf-f07e-a413-50d1d825a16c.png)

先ほどと同じように動かしてみましょう。

```java
public static void main(String[] args) {
	Product product = new Product();
	product.setId(1L);
	product.setName("キーボード");

	System.out.println(product.getId());
	System.out.println(product.getName());
}
```

```:コンソール
1
商品名: キーボード
```

とこのように自前で実装したgetterが呼ばれていることがわかります。

##まとめ
* 一部のフィールドにgetter、setterを作成したい場合は、フィールドに対してアノテーションを付与する。
* クラスのフィールドに共通的にgetter、setterを作成したい場合は、クラスに対してアノテーションを付与する。
* 一部のフィールドのgetter、setterを作成したくない場合は、`AccessLevel.NONE`を指定する。
* getter、setterの動作を単純な値取得、値セットから替えたい場合は、自前でgetter、setterを作成する。

##参考

* [@Getter and @Setter](https://projectlombok.org/features/GetterSetter)
* [Lombok - @Getter / @Setter](https://blog.y-yuki.net/entry/2016/10/12/003000)