web-dev-qa-db-ja.com

Lombok単一のクラスで@Builderと@Valueを一緒に使用できますか

まず、Lombokのおかげで、Javaコードがより洗練され、よりクリーンになりました。私のユースケースは、不変のクラスを作成したいです。そのために、@ Valueアノテーションを使用します。ビルダー機能を使用するには、@ Builderアノテーションを使用します。私の質問は、@ Builderと@Valueの両方を1つのクラスで一緒に使用できるかどうかです。これは、Lombokユーザー/開発者が推奨する良い方法ですか。

12
Anil

もちろんできます。確認するには、単に delombok コードを作成し、それが何を生成するかを確認します。この例を見てください:

@Builder
@Value
public class Pair {
    private Object left;
    private Object right;
}

デロンボキ化後、これは以下を生成します:

public class Pair {
    private Object left;
    private Object right;

    @Java.beans.ConstructorProperties({ "left", "right" })
    Pair(Object left, Object right) {
        this.left = left;
        this.right = right;
    }

    public static PairBuilder builder() {
        return new PairBuilder();
    }

    public Object getLeft() {
        return this.left;
    }

    public Object getRight() {
        return this.right;
    }

    public boolean equals(Object o) {
        if (o == this) return true;
        if (!(o instanceof Pair)) return false;
        final Pair other = (Pair) o;
        final Object this$left = this.left;
        final Object other$left = other.left;
        if (this$left == null ? other$left != null : !this$left.equals(other$left)) return false;
        final Object this$right = this.right;
        final Object other$right = other.right;
        if (this$right == null ? other$right != null : !this$right.equals(other$right)) return false;
        return true;
    }

    public int hashCode() {
        final int PRIME = 59;
        int result = 1;
        final Object $left = this.left;
        result = result * PRIME + ($left == null ? 0 : $left.hashCode());
        final Object $right = this.right;
        result = result * PRIME + ($right == null ? 0 : $right.hashCode());
        return result;
    }

    public String toString() {
        return "Pair(left=" + this.left + ", right=" + this.right + ")";
    }

    public static class PairBuilder {
        private Object left;
        private Object right;

        PairBuilder() {
        }

        public Pair.PairBuilder left(Object left) {
            this.left = left;
            return this;
        }

        public Pair.PairBuilder right(Object right) {
            this.right = right;
            return this;
        }

        public Pair build() {
            return new Pair(left, right);
        }

        public String toString() {
            return "Pair.PairBuilder(left=" + this.left + ", right=" + this.right + ")";
        }
    }
}

したがって、@Value@Builderの両方を明確に使用できます。

10
Justin

バージョン1.16.10の時点では、両方を使用する場合、コンストラクターはnot publicです。

これを補うために@AllArgsConstructorを追加できます。

7
Tom Andersen

簡単な回答:はい、いつでも@Valueと@Builderを一緒に使用できます。私はこれを製品コードで使用しましたが、正常に動作します。

長い答え:あなたはそれらを一緒に使うことができます。覚えておきたいことの1つは、@ Valueによって提供されるAllArgsConstructorは、lombokv1.16.0以降のパッケージに対してプライベートになるということです。したがって、それを公開したい場合は、@ AllArgsConstructorによって追加で制御にアクセスする必要があります。私の場合、プライベートコンストラクターが本当に欲しかったのです。 @Builderを使用する私の目的は、ビルダーを使用するだけでオブジェクトのインスタンス化を実際に許可し、後でコンストラクターまたはセッターメソッドを使用しないことでした。

これが私のコードです:


@Value
@Builder
@ApiModel(description = "Model to represent annotation")
public class Annotation {

    @NonNull
    @ApiModelProperty(value = "Unique identifier")
    private String id;

}

@ Eclipseの値型

Eclipseの@Builder tyoe

1
vikas