探究lombok-03-@Builder使用

Java 8

org.springframework.boot 2.7.3

lombok 1.18.24

Eclipse Version: 2022-09 (4.25.0)

--ben发布于博客园

 

上一篇:探究lombok-02-类继承

https://www.cnblogs.com/luo630/p/16941903.html

注,本文测试结果的 LombokMain.java 的代码与上一篇相同。ben发布于博客园

 

0、序章

使用 @Builder 后,可以使用 链式编程 方式构建对象(一般方法是使用 new)。ben发布于博客园

 

示例代码:UserBuilderVO类

import java.util.Date;
import java.util.List;

import lombok.Builder;

@Builder
public class UserBuilderVO {

	private Integer id;
	private String name;
	private List<String> tags;
	private Date createTime;
	
}

 

1、仅@Builder

只使用 @Builder 的类分析结果:

测试:class=class com.lib.webdemo.vo.UserBuilderVO
----
prtClasses: length=1
内部类: com.lib.webdemo.vo.UserBuilderVO.UserBuilderVOBuilder, com.lib.webdemo.vo.UserBuilderVO$UserBuilderVOBuilder, UserBuilderVOBuilder, com.lib.webdemo.vo.UserBuilderVO$UserBuilderVOBuilder, modifiers=9
----
prtConstructors: length=1
构造方法名称:com.lib.webdemo.vo.UserBuilderVO, 参数数量:4, modifiers=0
----
prtFields: length=4
字段:id, type=class java.lang.Integer, modifiers=2
字段:name, type=class java.lang.String, modifiers=2
字段:tags, type=interface java.util.List, modifiers=2
字段:createTime, type=class java.util.Date, modifiers=2
----
prtMethods: length=1
方法名称:builder, 参数数量:0, modifiers=9

增加了一个内部类UserBuilderVOBuilder;

只有一个成员方法:builder。

 

UserBuilderVOBuilder 类分析结果(1):

test(UserBuilderVO.UserBuilderVOBuilder.class);

测试:class=class com.lib.webdemo.vo.UserBuilderVO$UserBuilderVOBuilder
----
prtClasses: length=0
----
prtConstructors: length=1
构造方法名称:com.lib.webdemo.vo.UserBuilderVO$UserBuilderVOBuilder, 参数数量:0, modifiers=0
----
prtFields: length=4
字段:id, type=class java.lang.Integer, modifiers=2
字段:name, type=class java.lang.String, modifiers=2
字段:tags, type=interface java.util.List, modifiers=2
字段:createTime, type=class java.util.Date, modifiers=2
----
prtMethods: length=6
方法名称:name, 参数数量:1, modifiers=1
方法名称:toString, 参数数量:0, modifiers=1
方法名称:id, 参数数量:1, modifiers=1
方法名称:createTime, 参数数量:1, modifiers=1
方法名称:build, 参数数量:0, modifiers=1
方法名称:tags, 参数数量:1, modifiers=1

存在6个方法,其中一个为 build,用来生成 最终的 UserBuilderVO 对象。

 

链式编程 创建对象:

private static void testCreateUserBuilderVO() {
    cs.accept("\n\n测试:testCreateUserBuilderVO...");

    UserBuilderVO bvo = UserBuilderVO.builder()
        .id(1)
        .name("ben")
        .tags(new ArrayList<>())
        .createTime(new Date())
        .build();
    cs.accept("UserBuilderVO bvo=" + bvo);
}

测试结果:

测试:testCreateUserBuilderVO...
UserBuilderVO bvo=com.lib.webdemo.vo.UserBuilderVO@87aac27

 

直接输出对象,看不到对象里面各个属性的值;

也没有各个属性的getter方法,无法获取内部属性的值。

 

存在缺点:

无法用 链式编程 设置对象中 列表的值;(第3节)

对于 createTime,是否可以设置默认值?(第4节)

 

2、@Builder+@ToString+@Getter

给上面的 UserBuilderVO 类添加 @ToString、@Getter 注解。

 

类分析结果:多了 getter方法 和 ToString方法

prtMethods: length=6
方法名称:toString, 参数数量:0, modifiers=1
方法名称:getName, 参数数量:0, modifiers=1
方法名称:getId, 参数数量:0, modifiers=1
方法名称:builder, 参数数量:0, modifiers=9
方法名称:getCreateTime, 参数数量:0, modifiers=1
方法名称:getTags, 参数数量:0, modifiers=1

 

创建对象后输出结果:可以看到对象内部各个属性的值了

测试:testCreateUserBuilderVO...
UserBuilderVO bvo=UserBuilderVO(id=1, name=ben, tags=[], createTime=Mon Dec 05 19:23:44 CST 2022)

 

3、填充列表的值(@Singular)

在 第1节中,对 UserBuilderVOBuilder 类进行了分析,存在一个 tags方法。

此时,在链式编程中,需要提前建立一个列表作为参数传入。

要想在链式编程中设置tags属性的值,需要使用 @Singular 注解。

 

注,Singular adj.  <语>单数的; <正>突出的; 奇特的; 非凡的; n.  单数形式(的词)。ben发布于博客园

 

(在第2节的基础上)给 UserBuilderVO 的 tags 属性添加 @Singular 注解。

UserBuilderVO 的类分析结果不变。

但 UserBuilderVOBuilder 的类分析结果(2) 存在下面的变化:

测试:class=class com.lib.webdemo.vo.UserBuilderVO$UserBuilderVOBuilder
----
prtClasses: length=0
----
prtConstructors: length=1
构造方法名称:com.lib.webdemo.vo.UserBuilderVO$UserBuilderVOBuilder, 参数数量:0, modifiers=0
----
prtFields: length=4
字段:id, type=class java.lang.Integer, modifiers=2
字段:name, type=class java.lang.String, modifiers=2
字段:tags, type=class java.util.ArrayList, modifiers=2
字段:createTime, type=class java.util.Date, modifiers=2
----
prtMethods: length=8
方法名称:name, 参数数量:1, modifiers=1
方法名称:toString, 参数数量:0, modifiers=1
方法名称:id, 参数数量:1, modifiers=1
方法名称:createTime, 参数数量:1, modifiers=1
方法名称:build, 参数数量:0, modifiers=1
方法名称:tags, 参数数量:1, modifiers=1
方法名称:tag, 参数数量:1, modifiers=1
方法名称:clearTags, 参数数量:0, modifiers=1

多了 tag、clearTags 两个方法。

 

新的创建对象:链式编程 填充列表属性的值

private static void testCreateUserBuilderVO() {
    cs.accept("\n\n测试:testCreateUserBuilderVO...");

    UserBuilderVO bvo = UserBuilderVO.builder()
        .id(1)
        .name("ben")
        // 旧 tags 方法
//				.tags(new ArrayList<>())
        // 新 tag方法
        .tag("1").tag("2").tag("AAAA")
        .createTime(new Date())
        .build();
    cs.accept("UserBuilderVO bvo=" + bvo);
}

测试结果:

测试:testCreateUserBuilderVO...
UserBuilderVO bvo=UserBuilderVO(id=1, name=ben, tags=[1, 2, AAAA], createTime=Mon Dec 05 19:43:06 CST 2022)

tags现在有值了。

 

填充Map

添加字段scores:

类分析结果:

测试:class=class com.lib.webdemo.vo.UserBuilderVO
----
prtClasses: length=1
内部类: com.lib.webdemo.vo.UserBuilderVO.UserBuilderVOBuilder, com.lib.webdemo.vo.UserBuilderVO$UserBuilderVOBuilder, UserBuilderVOBuilder, com.lib.webdemo.vo.UserBuilderVO$UserBuilderVOBuilder, modifiers=9
----
prtConstructors: length=1
构造方法名称:com.lib.webdemo.vo.UserBuilderVO, 参数数量:5, modifiers=0
----
prtFields: length=5
字段:id, type=class java.lang.Integer, modifiers=2
字段:name, type=class java.lang.String, modifiers=2
字段:tags, type=interface java.util.List, modifiers=2
字段:scores, type=interface java.util.Map, modifiers=2
字段:createTime, type=class java.util.Date, modifiers=2
----
prtMethods: length=13
方法名称:toString, 参数数量:0, modifiers=1
方法名称:getName, 参数数量:0, modifiers=1
方法名称:getId, 参数数量:0, modifiers=1
方法名称:builder, 参数数量:0, modifiers=9
方法名称:access$1, 参数数量:0, modifiers=4104
方法名称:access$2, 参数数量:0, modifiers=4104
方法名称:getTags, 参数数量:0, modifiers=1
方法名称:getCreateTime, 参数数量:0, modifiers=1
方法名称:getScores, 参数数量:0, modifiers=1
方法名称:$default$name, 参数数量:0, modifiers=10
方法名称:access$0, 参数数量:0, modifiers=4104
方法名称:$default$id, 参数数量:0, modifiers=10
方法名称:$default$createTime, 参数数量:0, modifiers=10


测试:class=class com.lib.webdemo.vo.UserBuilderVO$UserBuilderVOBuilder
----
prtClasses: length=0
----
prtConstructors: length=1
构造方法名称:com.lib.webdemo.vo.UserBuilderVO$UserBuilderVOBuilder, 参数数量:0, modifiers=0
----
prtFields: length=9
字段:id$value, type=class java.lang.Integer, modifiers=2
字段:id$set, type=boolean, modifiers=2
字段:name$value, type=class java.lang.String, modifiers=2
字段:name$set, type=boolean, modifiers=2
字段:tags, type=class java.util.ArrayList, modifiers=2
字段:scores$key, type=class java.util.ArrayList, modifiers=2
字段:scores$value, type=class java.util.ArrayList, modifiers=2
字段:createTime$value, type=class java.util.Date, modifiers=2
字段:createTime$set, type=boolean, modifiers=2
----
prtMethods: length=11
方法名称:name, 参数数量:1, modifiers=1
方法名称:toString, 参数数量:0, modifiers=1
方法名称:id, 参数数量:1, modifiers=1
方法名称:tag, 参数数量:1, modifiers=1
方法名称:score, 参数数量:2, modifiers=1
方法名称:createTime, 参数数量:1, modifiers=1
方法名称:build, 参数数量:0, modifiers=1
方法名称:clearTags, 参数数量:0, modifiers=1
方法名称:clearScores, 参数数量:0, modifiers=1
方法名称:tags, 参数数量:1, modifiers=1
方法名称:scores, 参数数量:1, modifiers=1

 

测试代码及结果:

测试:testCreateUserBuilderVO...
UserBuilderVO bvo=UserBuilderVO(id=1, name=ben, tags=[1, 2, AAAA], 
scores={数学=100, 语文=99, 科学=98, 文明=97}, createTime=Mon Dec 05 19:55:43 CST 2022)

 

4、设置默认值(@Builder.Default)

UserBuilderVO 对象的属性默认是null,可以使用 @Builder.Default 设置各个属性的默认值。ben发布于博客园

更新后的 UserBuilderVO:

@Builder
@Getter
@ToString
public class UserBuilderVO {

	@Builder.Default
	private Integer id = 2;
	
	@Builder.Default
	private String name = "罗峰";
	
	@Singular
	private List<String> tags;
	
	@Builder.Default
	private Date createTime = new Date();
	
}

 

类分析:

测试:class=class com.lib.webdemo.vo.UserBuilderVO
----
prtClasses: length=1
内部类: com.lib.webdemo.vo.UserBuilderVO.UserBuilderVOBuilder, com.lib.webdemo.vo.UserBuilderVO$UserBuilderVOBuilder, UserBuilderVOBuilder, com.lib.webdemo.vo.UserBuilderVO$UserBuilderVOBuilder, modifiers=9
----
prtConstructors: length=1
构造方法名称:com.lib.webdemo.vo.UserBuilderVO, 参数数量:4, modifiers=0
----
prtFields: length=4
字段:id, type=class java.lang.Integer, modifiers=2
字段:name, type=class java.lang.String, modifiers=2
字段:tags, type=interface java.util.List, modifiers=2
字段:createTime, type=class java.util.Date, modifiers=2
----
prtMethods: length=12
方法名称:toString, 参数数量:0, modifiers=1
方法名称:getName, 参数数量:0, modifiers=1
方法名称:getId, 参数数量:0, modifiers=1
方法名称:builder, 参数数量:0, modifiers=9
方法名称:$default$id, 参数数量:0, modifiers=10
方法名称:$default$name, 参数数量:0, modifiers=10
方法名称:access$1, 参数数量:0, modifiers=4104
方法名称:getTags, 参数数量:0, modifiers=1
方法名称:access$2, 参数数量:0, modifiers=4104
方法名称:access$0, 参数数量:0, modifiers=4104
方法名称:getCreateTime, 参数数量:0, modifiers=1
方法名称:$default$createTime, 参数数量:0, modifiers=10


测试:class=class com.lib.webdemo.vo.UserBuilderVO$UserBuilderVOBuilder
----
prtClasses: length=0
----
prtConstructors: length=1
构造方法名称:com.lib.webdemo.vo.UserBuilderVO$UserBuilderVOBuilder, 参数数量:0, modifiers=0
----
prtFields: length=7
字段:id$value, type=class java.lang.Integer, modifiers=2
字段:id$set, type=boolean, modifiers=2
字段:name$value, type=class java.lang.String, modifiers=2
字段:name$set, type=boolean, modifiers=2
字段:tags, type=class java.util.ArrayList, modifiers=2
字段:createTime$value, type=class java.util.Date, modifiers=2
字段:createTime$set, type=boolean, modifiers=2
----
prtMethods: length=8
方法名称:name, 参数数量:1, modifiers=1
方法名称:toString, 参数数量:0, modifiers=1
方法名称:id, 参数数量:1, modifiers=1
方法名称:build, 参数数量:0, modifiers=1
方法名称:tag, 参数数量:1, modifiers=1
方法名称:clearTags, 参数数量:0, modifiers=1
方法名称:createTime, 参数数量:1, modifiers=1
方法名称:tags, 参数数量:1, modifiers=1

UserBuilderVO 的变化:方法里面多了 $default$ + 属性名、access$0~2。

UserBuilderVOBuilder 的变化:属性多了 属性名 + $value、属性名 + $set 格式的属性,少了 属性名 的属性、ben发布于博客园

 

创建对象:

cs.accept("\n\n测试:testCreateUserBuilderVO...");
UserBuilderVO bvo = UserBuilderVO.builder()
    .build();
cs.accept("UserBuilderVO bvo=" + bvo);

测试结果:

测试:testCreateUserBuilderVO...
UserBuilderVO bvo=UserBuilderVO(id=2, name=罗峰, tags=[], createTime=Mon Dec 05 19:56:21 CST 2022)

 

更多测试:

@Singular 和 @Builder.Default 不可以同时存在。ben发布于博客园

 

 

疑问:

@Data 是否有什么更进一步的用法呢?ben发布于博客园

 

@Builder 的更多使用方式,可以看 参考资料#1 —— 来自官方

 

参考资料

1、官方文档-@Builder

https://projectlombok.org/features/Builder

讲的很详细。基本用法、高级用法。ben发布于博客园

2、Lombok 中@Builder 的使用

https://www.cnblogs.com/minmin123/p/14368725.html

posted @ 2021-02-03 18:27  keepsummer

3、

 

ben发布于博客园

 

posted @ 2022-12-05 19:55  快乐的凡人721  阅读(43)  评论(0编辑  收藏  举报