Lombok でできること確認します。( @Value )

2021年5月6日

この投稿では Lombok の @Value について書きたいと思います。
私は未熟なためこの属性がいったいどこで使えるのか未だ理解できていません。
どんな機能なのかだけでも確認しておきたいと思います。

全フィールド、一度設定したら再設定不可!?

公式サイトによると・・・

@Value is the immutable variant of @Data; all fields are made private and final by default, and setters are not generated. The class itself is also made final by default, because immutability is not something that can be forced onto a subclass. Like @Data, useful toString(), equals() and hashCode() methods are also generated, each field gets a getter method, and a constructor that covers every argument (except final fields that are initialized in the field declaration) is also generated.

とあります。大雑把に訳すと すべてのフィールドはprivateでfinalとなり、クラス自体もfinalとなるそうです。
フィールドの設定はオブジェクトを生成時のみ、各フィールドへのアクセスもゲッターのみという徹底っぷりです。
まさに不変のオブジェクトということですね😐
ほかにも@ToStringや@EqualsAndHashCodeも付与されるそうです。

試してみた

では試してみましょう。

package com.example.demo;

import lombok.Value;

@Value
public class HogeLombok {
	public int age;
	public String name;
}

今回わざとpublicなフィールドで実装してみました😏
コンパイルエラーが出るかなぁ・・なんて期待していたのですが特に反応もなく残念。

HogeLombokを継承しようとしたのですがこれはコンパイルエラー。
クラス自身にfinalが修飾されたことがわかりました。

ageのセッターを呼び出そうと思ったのですがコンパイルエラー。ゲッターは呼び出せました。
nameについても同様でした。

 

確認

以下のように実装して確認をしてみます。

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;


@SpringBootApplication
public class DemoApplication {

	public static void main(String[] args) {
		SpringApplication.run(DemoApplication.class, args);
		
		// インスタンス化!
		HogeLombok v01 = new HogeLombok(20, "太郎");
		//v01.setAge(30);
		//int v1Age = v01.getAge();
		HogeLombok v02 = new HogeLombok(20, "太郎");
		//v02.setAge(30);
		//int v2Age = v02.getAge();
		
		System.out.println("v01 と v02 は" + (v01.equals(v02) ? "同じ人" : "違う人"));
		System.out.println("v01 " + v01);
		System.out.println("v02 " + v02);
	}
}

 

結果はこうなりました。

同じ人となりました。@EqualsAndHashCodeですね。
フィールドの値が出力されたことで @ToStringも確認できました。

余談

ageフィールドをpublicで修飾したのを覚えてますか?
「すべてのフィールドをprivateで修飾するんだからアクセスできないでしょ」なんて思っていたら・・・。

全く問題なく参照できてしまいました・・・。
このあと

v01.age = 50;

も試しましたがさすがにコンパイルエラーでした。
privateなフィールドになるんじゃないの????。

どうやら修飾子を省略するとprivateになるようです。
Lombokを使うときは修飾子を明示的に記述しないほうがよいのでしょうか?

まとめ

public修飾したフィールドの件は謎ですが機能としては理解しました。
あとは使い道ですね。今は「高度な実装の時に使う!」とだけ覚えておくことにします!

 

今日はここまで~