简体   繁体   English

Lombok我们可以将@Builder和@Value一起用于单个类

[英]Lombok Can we use @Builder and @Value together on a single class

First of all thanks to Lombok, our java code is now much sleeker and cleaner. 首先感谢Lombok,我们的Java代码现在更加流畅和清洁。 My use case is I want to create an immutable class. 我的用例是我想创建一个不可变的类。 For that I would use @Value annotation. 为此我会使用@Value注释。 Also I want to use builder capabilities, for that I would use @Builder annotation. 另外我想使用构建器功能,因为我会使用@Builder注释。 My question is if we can use both @Builder and @Value together on a single class. 我的问题是,如果我们可以在一个类上同时使用@Builder和@Value。 Is it a good practice recommended by Lombok users/developers. 这是Lombok用户/开发人员推荐的好习惯。

Of course you can. 当然可以。 To check, simply delombok your code and see what it generates. 要检查,只需简化代码并查看它生成的内容。 Take this example: 举个例子:

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

After delombokification, this produces: 在delombokification之后,这产生:

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 + ")";
        }
    }
}

So you can clearly use both @Value and @Builder 所以你可以清楚地使用@Value@Builder

As of version 1.16.10, the constructor is not public when you use both. 从版本1.16.10开始,当您同时使用它们时,构造函数公开。

You can add @AllArgsConstructor to compensate for this. 您可以添加@AllArgsConstructor来弥补这一点。

Short Answer: Yes, you can always use @Value and @Builder together. 简答:是的,您可以随时使用@Value和@Builder。 I have used this in my production code and it works fine. 我在我的生产代码中使用了它,它工作正常。

Long Answer: You can use them together. 答案:你可以一起使用它们。 The one thing you want to keep in mind is that the AllArgsConstructor provided by @Value will be private to package since lombok v1.16.0. 你要记住的一件事是@value提供的AllArgsConstructor自lombok v1.16.0起将是私有包。 So, if you want that to be public you will have to access control that additionally by @AllArgsConstructor. 因此,如果您希望公开,则必须通过@AllArgsConstructor访问控制权。 In my case though, private constructor is what I really wanted. 在我的情况下,私有构造函数是我真正想要的。 My aim of using @Builder was to really allow the the object instantiation only using the builder and not use constructor or setter methods later. 我使用@Builder的目的是仅使用构建器实际允许对象实例化,而不是稍后使用构造函数或setter方法。

Here is my code: 这是我的代码:


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

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

}

@Value type from eclipse 来自eclipse的@Value类型

@Builder tyoe from eclipse 来自日食的@Builder tyoe

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM