Using Lombok’s @Builder Annotation – 使用Lombok’的@Builder注释

最后修改: 2018年 5月 23日

1. Overview

1.概述

Project Lombok’s @Builder is a helpful mechanism for using the Builder pattern without writing boilerplate code. We can apply this annotation to a Class or a method.

Project Lombok的@Builder是一种有用的机制,用于使用Builder模式,而无需编写模板代码。我们可以将此注解应用于或方法。

In this quick tutorial, we’ll look at the different use cases for @Builder.

在这个快速教程中,我们将看一下@Builder的不同使用情况。

2. Maven Dependencies

2.Maven的依赖性

First, we need to add Project Lombok to our pom.xml:

首先,我们需要将Project Lombok加入我们的pom.xml

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.20</version>
</dependency>

Maven Central has the latest version of Project Lombok here.

Maven Central有最新版本的Project Lombok,

3. Using @Builder on a Class

3.在一个类上使用@Builder

In the first use case, we’re merely implementing a Class, and we want to use a builder to create instances of our class.

在第一个用例中,我们只是实现了一个,我们想用一个构建器来创建我们类的实例。

The first and only step is to add the annotation to the class declaration:

第一步也是唯一的一步是在类声明中添加注解。

@Getter
@Builder
public class Widget {
    private final String name;
    private final int id;
}

Lombok does all the work for us. We can now build a Widget and test it:

Lombok为我们做了所有的工作。我们现在可以建立一个Widget并测试它。

Widget testWidget = Widget.builder()
  .name("foo")
  .id(1)
  .build();

assertThat(testWidget.getName())
  .isEqualTo("foo");
assertThat(testWidget.getId())
  .isEqualTo(1);

If we want to create copies or near-copies of objects, we can add the property toBuilder = true to the @Builder annotation:

如果我们想创建对象的副本或近似副本,我们可以将属性toBuilder = true添加到@Builder注释

@Builder(toBuilder = true)
public class Widget {
//...
}

This tells Lombok to add the toBuilder() method to our Class. When we invoke the toBuilder() method, it returns a builder initialized with the properties of the instance it’s called on:

这告诉Lombok将toBuilder()方法添加到我们的Class。当我们调用toBuilder()方法时,它返回一个初始化了它所调用的实例的属性的构建器:

Widget testWidget = Widget.builder()
  .name("foo")
  .id(1)
  .build();

Widget.WidgetBuilder widgetBuilder = testWidget.toBuilder();

Widget newWidget = widgetBuilder.id(2).build();
assertThat(newWidget.getName())
  .isEqualTo("foo");
assertThat(newWidget.getId())
  .isEqualTo(2);

We can see in the test code that the builder class generated by Lombok is named like our class with “Builder” appended to it, WidgetBuilder in this case. We can then modify the properties we want, and build() a new instance.

我们可以在测试代码中看到,Lombok生成的构建器类的名字和我们的类一样,后面加了“Builder”WidgetBuilder在这种情况下.我们可以修改我们想要的属性,并build()一个新实例。

If we need to specify the required fields, we can use the annotation configuration to create an auxiliary builder:

如果我们需要指定所需的字段,我们可以使用注释配置来创建一个辅助的构建器。

@Builder(builderMethodName = "internalBuilder")
public class RequiredFieldAnnotation {
    @NonNull
    private String name;
    private String description;

    public static RequiredFieldAnnotationBuilder builder(String name) {
        return internalBuilder().name(name);
    }
}

In this case, we’re hiding the default builder as internalBuilder and creating our own. Thus, when we create the builder, we must provide the required parameter:

在这种情况下,我们将默认的builder隐藏为internalBuilder并创建我们自己的。因此,当我们创建构建器时,我们必须提供所需的参数。

RequiredField.builder("NameField").description("Field Description").build();

Also, to make sure our field exists, we can add the @NonNull annotation.

另外,为了确保我们的字段存在,我们可以添加@NonNull注释。

4. Using @Builder on a Method

4.在一个方法上使用@Builder

Suppose we’re using an object that we want to construct with a builder, but we can’t modify the source or extend the Class.

假设我们正在使用一个我们想用构建器来构建的对象,但我们不能修改源码或扩展

First, let’s create a quick example using Lombok’s @Value annotation:

首先,让我们使用Lombok的@Value注解创建一个快速实例:

@Value
final class ImmutableClient {
    private int id;
    private String name;
}

Now we have a final Class with two immutable members, getters for them, and an all-arguments constructor.

现在我们有一个final Class,有两个不可变的成员,它们的getters,和一个全参数构造函数。

We covered how to use @Builder on a Class, but we can also use it on methods. We’ll use this ability to work around not being able to modify or extend ImmutableClient.

我们介绍了如何在上使用@Builder,但我们也可以在方法上使用它。我们将利用这种能力来解决无法修改或扩展ImmutableClient的问题。

Then we’ll create a new class with a method for creating ImmutableClients:

然后我们将创建一个新的类,其中有一个创建ImmutableClients的方法。

class ClientBuilder {

    @Builder(builderMethodName = "builder")
    public static ImmutableClient newClient(int id, String name) {
        return new ImmutableClient(id, name);
    }
}

This annotation creates a method named builder() that returns a Builder for creating ImmutableClients.

该注解创建了一个名为builder()的方法,返回一个Builder用于创建ImmutableClients

Now let’s build an ImmutableClient:

现在让我们建立一个ImmutableClient

ImmutableClient testImmutableClient = ClientBuilder.builder()
  .name("foo")
  .id(1)
  .build();
assertThat(testImmutableClient.getName())
  .isEqualTo("foo");
assertThat(testImmutableClient.getId())
  .isEqualTo(1);

5. Conclusion

5.结论

In this brief article, we used Lombok’s @Builder annotation on a method to create a builder for a final Class, and we learned how to make some of the Class fields required.

在这篇简短的文章中,我们在一个方法上使用了Lombok的@Builder注解来创建一个final Class的构建器,并且我们学习了如何使一些Class字段成为必填项。

Code samples, as always, can be found over on GitHub.

像往常一样,可以在GitHub上找到代码样本