Lombok的 @Builder 使用教程

812 阅读3分钟

Lombok的@Builder 注解是一种实现构建器模式的有用技术,旨在减少模板代码。在本教程中,我们将学习如何将@Builder应用于一个类以及其他有用的功能。

确保你已经在项目中包含了Lombok,并在IDE中安装了Lombok支持

如果我们想用Jackson来marshal或unmarshal builder类,那么我们应该使用@Jacksonized 注解。

1.1.@Builder

@Builder注解为被注解的POJO类产生复杂的构建器API。

例如,如果我们用*@Builder注解来注解一个Article 类,我们可以使用构建器API来创建Article实例。在内部,一个类ArticleBuilder 和一个build() 方法被自动生成,并为构建器类的每个参数提供类似setter*的方法。

import java.util.List;
import lombok.Builder;
import lombok.Getter;
import lombok.ToString;

@Builder
@Getter
@ToString
public class Article {
  private Long id;
  private String title;
  private List<String> tags;
}
Article a = Article.builder()
  .id(1L)
  .title("Test Article")
  .tags(Collections.singletonList("Demo"))
  .build();

@Getter 注解增加了访问器方法,@ToString 注解覆盖了toString() 方法,打印了相关字段的值。

2.@Singular方法支持

使用@Singular与@Builder为自动生成的类中的集合参数/字段生成单一的方法。这个单数方法可以向集合中添加一个单项。请注意,@Singular注解也支持Guava的集合类

例如,当我们在tags 字段中添加@Singular。

@Builder
@Getter
@ToString
public class Article {
  private Long id;
  private String title;

  @Singular
  private List<String> tags;
}

我们可以在文章类构建器中实现以下行为。

Article a = Article.builder()
      .id(1L)
      .title("Test Article")
      .tag("TestTag1")
      .tag("TestTag2")
      .build(); 

3.默认值的@Builder.Default

有时,如果客户端在创建实例时没有填充字段,我们想给该字段分配一个默认值。在这种情况下,我们可以对这些字段使用*@Builder.Default*。

@Builder
@Getter
@ToString
public class Article {
  private Long id;

  @Builder.Default
  private String title = "Title Placeholder";

  @Singular
  private List<String> tags;
}

在上面的例子中,如果我们在一个新的实例中没有指定title的值,它将被设置为 "Title Placeholder"。

Article a = Article.builder()
  .id(1L)
  .tag("TestTag1")
  .tag("TestTag2")
  .build();

// Article(id=1, title=Title Placeholder, tags=[TestTag1, TestTag2])
System.out.println(a);  

4.创建原型实例

原型实例是一个现有对象的副本,而不是从头开始创建一个新的实例。我们可以通过使用@Builder(toBuilder = true) ,并在任何现有的实例上使用toBuilder() 方法来实现这个功能。

@Builder(toBuilder = true)
@Getter
@ToString
public class Article {
    private Long id;

    @Builder.Default
    private String title = "Title Placeholder";

    @Singular
    private List<String> tags;
}

请注意,在第二个实例中,文章的标题已经改变,但其他字段与第一个实例相同。

Article a = Article.builder()
  .id(1L)
  .title("Test Article")
  .tag("Demo")
  .build();

//Article(id=1, title=Test Article, tags=[Demo])
System.out.println(a);

Article.ArticleBuilder nearCopyBuilder = a.toBuilder();
Article b = nearCopyBuilder.title("Final Title").build();

//Article(id=1, title=Final Title, tags=[Demo])
System.out.println(b);

5.实例的必要参数

如果我们的文章类实例没有文章id ,那么它就没有意义了。它应该是一个强制性的字段。为了使字段成为强制性的,我们需要添加我们自己的ArticleBuilder类,将必填字段作为构造函数参数。

另外,如果我们想确保客户端没有传递null ,以满足所需的输入验证,不要忘记添加@NonNull 注释。

@Builder
@Getter
@ToString
public class Article {
  @NonNull
  private final Long id;
  private String title = "Title Placeholder";
  @Singular
  private final List<String> tags;

  public static ArticleBuilder builder(final Long id) {
    return new ArticleBuilder().id(id);
  }
}
Article a = Article.builder(1L)
  .title("Test Article")
  .tag("Data")
  .build();

//Article(id=1, title=Test Article, tags=[Data])
System.out.println(a);

6.总结

Lombok @Builder注解是将构建器模式引入POJO类的一种很好的方式。它支持所有种类的操作和配置,包括marshaling和unmarshalling。

请参考官方文档,了解最新添加的功能和任何问题。

学习愉快!!

源代码下载