きり丸の技術日記

技術検証したり、資格等をここに残していきます。

JavaのLombokのWithアノテーションを素振りした

個人用ネタ。

今回素振りするのは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.com

前々から勉強しようとは思っていたのですが、技術記事は自分が困ってはじめて腹落ちすることが多くて、事前に読んでも挙動が理解できず…。

まだまだ自分のレベルの低さを実感します。今後も地道に勉強して、勉強した内容を布教できるエンジニアになりたいです。


この記事がお役に立ちましたら、各種SNSでのシェアや、今後も情報発信しますのでフォローよろしくお願いします。

参考情報