在Lombok v0.12.0中作为实验功能引入
自v1.16.0起获得了 @Singular 支持并被升级到了主要lombok软件包
@Builder、@Singular自lombok v1.16.8起,使用可以添加明确的方法
@Builder.Default* v1.16.16中添加了功能
@Builder(builderMethodName = “”) 从=1.18.8开始是合法的(并且将抑制生成器方法的生成)
@Builder(access = AccessLevel.PACKAGE) 从lombok v1.18.8开始是合法的(并将生成具有指定访问级别的构建器类,构建器方法等)
功能
@Builder
注解为你的类提供复杂的建造者模式 API。
@Builder 使你可以自动生成使您的类可实例化的代码,例如:
Person.builder() .name("AdamSavage") .city("SanFrancisco") .job("Mythbusters") .job("Unchained Reaction") .build();
使用位置
@Builder
可以放在类,构造器或方法上。虽然“基于类”和“基于构造器”模式是最常见的用例,但使用“方法”用例最容易解释。
public class ResponseMessage extends Message<OperationResult> { private ResponseMessage(MessageHeader messageHeader, OperationResult messageBody) { super(messageHeader, messageBody); } public Class getMessageBodyDecodeClass(int opcode) { return OperationType.fromOpCode(opcode).getOperationResultClazz(); } public static ResponseMessage.ResponseMessageBuilder builder() { return new ResponseMessage.ResponseMessageBuilder(); } public ResponseMessage() { } public static class ResponseMessageBuilder { private MessageHeader messageHeader; private OperationResult messageBody; ResponseMessageBuilder() { } public ResponseMessage.ResponseMessageBuilder messageHeader(MessageHeader messageHeader) { this.messageHeader = messageHeader; return this; } public ResponseMessage.ResponseMessageBuilder messageBody(OperationResult messageBody) { this.messageBody = messageBody; return this; } public ResponseMessage build() { return new ResponseMessage(this.messageHeader, this.messageBody); } public String toString() { return "ResponseMessage.ResponseMessageBuilder(messageHeader=" + this.messageHeader + ", messageBody=" + this.messageBody + ")"; } } }
被**@Builder**注解的方法(从现在开始称为target)将生成以下7件事:
即构造内部类,在内部类赋值属性,build时调用含有所有属性的构造方法创建对象。
一个内部静态类,名为FooBuilder,其类型参数与静态方法相同(称为builder)
在构建器中:目标的每个参数有一个private非static 非 final 字段
在builder中:包私有的无参数空构造器
在builder中:对目标的每个参数使用类似 setter 的方法:与该参数具有相同的类型和相同的名称。它返回构建器本身,以便可以将setter调用链接起来
在builder中:build()调用该方法的方法,并在每个字段中传递。它返回与目标返回相同的类型
有意义的toString()实现
在包含target的类中:一个builder()方法,该方法创建builder的新实例
如果该元素已存在,则每个列出的生成元素都将被静默跳过(忽略参数计数并仅查看名称)。这包括构建器本身:如果该类已经存在,则lombok会简单地开始在此现有类中注入字段和方法,除非要注入的字段/方法当然已经存在。但是,您不能在生成器类上放置生成lombok批注的任何其他方法(或构造函数)。例如,您不能放入@EqualsAndHashCodebuilder类。
@Builder可以为收集参数/字段生成所谓的“奇异”方法。它们采用1个元素而不是整个列表,然后将该元素添加到列表中。例如:Person.builder().job(“Mythbusters”).job(“Unchained Reaction”).build();将导致该List jobs字段中包含2个字符串。要获得此行为,必须使用注释字段/参数@Singular。该功能具有其自己的文档。
现在,“方法”模式已经很清楚了,@Builder在构造函数上添加注释的功能类似。实际上,构造函数只是具有特殊语法以调用它们的静态方法:它们的“返回类型”是它们构造的类,并且它们的类型参数与类本身的类型参数相同。
应用于@Builder类就像是将其添加@AllArgsConstructor(access = AccessLevel.PACKAGE)到该类并将@Builder注释应用于此all-args-constructor一样。仅当您自己未编写任何显式构造函数时,此方法才有效。如果确实有显式构造函数,则将@Builder注释放在构造函数上而不是在类上。请注意,如果将@Value和@Builder都放在类上,则@Builder要生成“ wins”的程序包私有构造函数,而禁止@Value要生成的构造函数。
如果@Builder用于生成生成器来生成您自己的类的实例(除非添加@Builder到不返回您自己的类型的方法中,否则通常都是这种情况),您还可以@Builder(toBuilder = true)在类中使用生成实例方法toBuilder();它创建一个新的构建器,该构建器以该实例的所有值开始。您可以将@Builder.ObtainVia注释放在参数(对于构造函数或方法的情况)或字段(对于@Builder类型的情况)上,以指示从该实例获取该字段/参数的值的替代方法。例如,您可以指定要调用的方法:@Builder.ObtainVia(method = “calculateFoo”)。
builder类的名称为FoobarBuilder,其中Foobar是目标的返回类型的简化的,以标题区分大小写的形式-即,@Builderon构造函数和类型的类型名称,以及@Builderon方法的返回类型的名称。。例如,如果@Builder应用于名为的类com.yoyodyne.FancyList,则构建器名称将为FancyListBuilder。如果@Builder将应用于返回的方法,void则将命名构建器VoidBuilder。
构建器的可配置方面包括:
该生成器的类名(默认:返回类型+“生成器”)
该版本()方法的名称(默认:“build”)
该生成器()方法的名称(默认:“builder”)
如果需要toBuilder()(默认值:否)
所有生成的元素的访问级别(默认值:)public。
(不推荐使用)如果您希望构建器的“ set”方法具有前缀,即Person.builder().setName(“Jane”).build()而不是前缀,Person.builder().name(“Jane”).build()则应为前缀。
用法示例,其中所有选项均从其默认值更改:
@Builder(builderClassName = “HelloWorldBuilder”, buildMethodName = “execute”, builderMethodName = “helloWorld”, toBuilder = true, access = AccessLevel.PRIVATE, setterPrefix = “set”)
想要将构建器与JSON / XML工具Jackson一起使用?我们涵盖了:检查@Jacksonized功能。
子类如何使用 @Build 注解?
- 父类
- 子类
- 同时在子类和全参数的构造器使用 @Builder 注解,最终的 build() 函数只返回了空参的构造器创建的一个子类对象,因此属性“采用 builder 方式设置的 字段最终都丢失了。
如果成员被注解,则必须是构造器或方法。如果对类注解,则会生成一个private构造器,并将所有字段作为参数,就像在类上存在 @AllArgsConstructor(AccessLevel.PRIVATE) ,就好像该构造器已经存在而是用@Builder注解。
将其加到类上,相当于包含所有属性的私有构造器,且构造器加上 @Builder 注解。
参考
https://projectlombok.org/features/Builder