Lombok:我们可以在单个类上同时使用@Builder和@Value吗?

23

首先感谢Lombok,我们的java代码现在更加简洁和清晰。 我的使用情况是我想创建一个不可变类。为此,我将使用@Value注释。此外,我想使用构建器功能,因此我将使用@Builder注释。我的问题是是否可以在单个类上同时使用@Builder和@Value。这是Lombok用户/开发者推荐的良好实践吗。


1
嗨@BranislavLazic,是的,我试过了。我的问题更多是关于其他人是否也遇到了这种情况,以及这是否是推荐的做法。 - Anil
3个回答

18

当然可以。要检查,只需delombok您的代码并查看它生成了什么。以此示例为例:

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

进行delombok处理后,这将产生:

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


1
顺便提一下,你可以通过省略单个字段的 private 访问修饰符来写更少的代码,因为根据 Lombok 的 @Value 注解文档所述 - "... 字段默认情况下是 privatefinal 。" - Peter Sivák

17

从版本1.16.10开始,当您同时使用两者时,构造函数是公共的。

您可以添加@AllArgsConstructor来弥补此问题。


是的,如果同时使用@Value@Builder,构造函数将变为包私有。 - Rothin Sen

4
简短回答:是的,你可以始终将 @Value 和 @Builder 一起使用。我在生产代码中使用过它们,并且运行良好。
长回答:你可以将它们结合使用。需要注意的一点是,自 lombok v1.16.0 开始,@Value 提供的 AllArgsConstructor 将是包私有的。因此,如果你想要它是公开的,你需要通过 @AllArgsConstructor 进一步控制访问权限。但在我的情况下,私有构造函数正是我所需要的。我使用 @Builder 的目的是仅允许使用构建器来实例化对象,而不是稍后使用构造函数或设置方法。
以下是我的代码:

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

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

}

@Value类型来自Eclipse

@Builder类型来自Eclipse


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接