個人用ネタ。
今回素振りするのはLombokのWithアノテーションです。他の言語でも同様の機能を達成したいときにwith
という名前を使ってみてはいかがでしょうか。おそらく、Javaに限らず他言語でも通用するメソッドです。
環境
- Java
- 17
ゴール
LombokのWithアノテーションを理解する。
機能
Withアノテーションはwith + 変数名
というメソッドを作成します。
機能としては、インスタンスの一部の変数を変更しつつ、新しいインスタンスを作成するときに使用します。
setterは同一インスタンスの値を変更するという点で違います。また、返却がvoidですので、メソッドをつなげることができません。
コード
With
アノテーションはクラスまたはメンバー変数に付与できます。クラスに付与した場合はすべてのメンバー変数に対してwith + 変数名
のメソッドを作成します。メンバー変数の場合は付与したメンバー変数のwith + 変数名
のメソッドを作成します。
static class WithExample { @With(AccessLevel.PROTECTED) @NonNull private final String name; private final int age; public WithExample(String name, int age) { if (name == null) { throw new NullPointerException(); } this.name = name; this.age = age; } }
static class WithExample { private @NonNull final String name; private final int age; public WithExample(String name, int age) { if (name == null) throw new NullPointerException(); this.name = name; this.age = age; } // 生成されるメソッド protected WithExample withName(@NonNull String name) { if (name == null) throw new java.lang.NullPointerException("name"); return this.name == name ? this : new WithExample(name, age); } }
ユースケース
正常系のデータを用意しておいて、一部の値を変更して異常とするテストがあった時、余計な情報が入ってこなくて便利です。
個人的に愛用しているBuilderパターンと比較しても、with
メソッドを使用したほうが非常に見やすいです。
@Builder(toBuilder = true) @AllArgsConstructor @With static class Condition { boolean a; } @Test void test() { Condition success = new Condition(true); assertThat(success.toBuilder().a(false).build().a).isFalse(); assertThat(success.withA(false).a).isFalse(); }
備考
onMethod
, onParam
というパラメータでメソッドとパラメータに対して追加でアノテーションを付与できそうです。ただヘルプを見ていて、どのように使うのか、どのようなユースケースで使えるかわかりませんでした。すみません。
ソースコード
終わりに
JavaのRecordにWith
メソッドが欲しいという記事がGitHubに上がっているというTwitterを見て、ようやくLombok側のWith
メソッドで解決したい悩みが分かりました。
twitter.comJavaのRecordsで一部を変更したコピーを作る構文を導入する話。なにより、こういう文書がGitHubに置かれるようになったのがおもしろい。
— きしだൠ(K1S) (@kis) 2020年8月19日
---
record MyRec(int x, int y){}
MyRec rec1 = new MyRec(1, 2);
MyRec rec2 = rec1 with {x = 3; }https://t.co/yU2wZ4kLtz
前々から勉強しようとは思っていたのですが、技術記事は自分が困ってはじめて腹落ちすることが多くて、事前に読んでも挙動が理解できず…。
まだまだ自分のレベルの低さを実感します。今後も地道に勉強して、勉強した内容を布教できるエンジニアになりたいです。
この記事がお役に立ちましたら、各種SNSでのシェアや、今後も情報発信しますのでフォローよろしくお願いします。