Lombok 子类如何使用 @Builder

Stella981
• 阅读 701

点击上方 "编程技术圈"关注, 星标或置顶一起成长

Lombok 子类如何使用 @Builder

后台回复“大礼包”有惊喜礼包!

每日英文

Miracles sometimes occur, but you have to work terribly for them.

奇迹有时候是会发生的,但是你得为之拼命的努力。

每日掏心话

无须匆忙,该来的总是会来,在对的时间,对的人,因为对的理由。

来自:jitwxs | 责编:乐乐

链接:jitwxs.cn/54621f54.html

编程技术圈(ID:study_tech)第 1117 次推文

往日回顾:程序员真的是太太太太太太太太难了!

正文

一、前言

业务开发中,子类父类还算是经常用到,Lombok 的 @builder 提供的链式调用帮助我们更轻松的创建对象。但是实验后却发现子类的 @Builder 是不会包含父类的属性。

假设存在父类 A:

`@Data
@Builder
public class A {
    private String aName;

    private String aAge;
}
`

存在子类 B:

`@Builder
@Data
@EqualsAndHashCode(callSuper = true)
public class B extends A {
    private String bName;

    private String bAge;
}
`

使用 builder 进行初始化时,类 A 可以正常创建,类 B 仅可以初始化自己的属性,父类属性无法初始化。

Lombok 子类如何使用 @Builder

二、解决:构造方法


查阅网络后,一种解决方法是利用构造方法:

  • 父类生成全参构造方法

  • 子类手动声明全参构造方法

  • 将子类 @builder 注解移动全参构造方法上,并设置 builderMethodName

`@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class A {
    private String aName;

    private String aAge;
}
`

`@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class B extends A {
    private String bName;

    private String bAge;

    @Builder(builderMethodName = "childBuilder")
    public B(String aName, String aAge, String bName, String bAge) {
        super(aName, aAge);
        this.bName = bName;
        this.bAge = bAge;
    }
}
`

修改 Main 方法如下:

`public class BuilderMain {
    public static void main(String[] args) {
        A xxx = A.builder()
                .aName("xxx")
                .aAge("111")
                .build();
        B yyy = B.childBuilder()
                .aName("xxx")
                .aAge("111")
                .bName("yyy")
                .bAge("222")
                .build();

        System.out.println(xxx);
        System.out.println(yyy);
    }
}
`

代码运行后,能得到正确结果:

A(aName=xxx, aAge=111) B(super=A(aName=xxx, aAge=111), bName=yyy, bAge=222)

但是这种方式弊端也很明显:

  • 子类调用父类的全参构造,当父类参数数量、顺序调整时,子类也需要同步调整。

  • 如果父类参数过多,构造方法十分不优雅。

三、解决:SuperBuilder

Lombok 自 v1.18.2 开始,为了解决这个问题,引入了 @SuperBuilder 注解,使用该注解,就可以很容易解决这个问题。在公众号顶级架构师后台回复“架构整洁”,获取一份惊喜礼包。

修改代码如下:

`@Data
@SuperBuilder
public class A {
    private String aName;

    private String aAge;
}
`

`@SuperBuilder
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class B extends A {
    private String bName;

    private String bAge;
}
`

Main 方法保持不变,代码运行后,能得到正确结果:

A(aName=xxx, aAge=111) B(super=A(aName=xxx, aAge=111), bName=yyy, bAge=222)

另外自 v1.18.4 也给 SuperBuilder 引入了toBuilder 参数,可以很方便的进行浅拷贝对象,效率虽然比手动 builder 慢一点,但也算是挺快的。

`@Data
@SuperBuilder(toBuilder = true)
public class A {
    private String aName;

    private String aAge;
}
`

给 B 加入属性 C,测试对象拷贝:

`@SuperBuilder(toBuilder = true)
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class B extends A {
    private String bName;

    private String bAge;

    private C c;
}
`

~

@AllArgsConstructor public class C {     private String name; }

输出结果如下:

`public class BuilderMain {
    public static void main(String[] args) {
        B b = B.builder()
                .aName("xxx")
                .aAge("111")
                .bName("yyy")
                .bAge("222")
                .c(new C("zhangsan"))
                .build();

        System.out.println(b);
        System.out.println(b.toBuilder().build());
    }
}
`

B(super=A(aName=xxx, aAge=111), bName=yyy, bAge=222, c=com.github.jitwxs.demo.builder.C@52cc8049) B(super=A(aName=xxx, aAge=111), bName=yyy, bAge=222, c=com.github.jitwxs.demo.builder.C@52cc8049)

四、彩蛋

由于 @SuperBuilder 刚引入不久,所以还是有一些 BUG 的,比如当你的 SpringBoot 版本为 2.2.3.RELEASE 时,或者你的 Lombok 版本低于 v1.18.12 时,使用上文的例子,你就会发现竟然无法通过编译。

Lombok 子类如何使用 @Builder

实际的原因是不支持用 B 来命名类,简直是吐出一口老血,好在升级到 v1.18.12 版本后就修复了这个问题,可能这就是给不规范命名的人埋的坑吧,哈哈。

PS: 欢迎在留言区留下你的观点,一起讨论提高。如果今天的文章让你有新的启发,欢迎转发分享给更多人。

版权申明:内容来源网络,版权归原创者所有。除非无法确认,我们都会标明作者及出处,如有侵权烦请告知,我们会立即删除并表示歉意。谢谢!

欢迎加入后端架构师交流群,在后台回复“学习”即可。

Lombok 子类如何使用 @Builder

猜你还想看

阿里、腾讯、百度、华为、京东最新面试题汇集

字节跳动员工晒出税后工资,网友:怀疑你是日薪

又一起“删库”跑路:链家程序员怒删公司 9TB 数据,被判 7 年!网友:真惨~

真能一快遮百丑?为什么要弃坑FastJson

BAT等大厂Java面试经验总结

Lombok 子类如何使用 @Builder

别找了,想获取 Java大厂面试题学习资料

扫下方二维码回复「手册」就好了

**嘿,你在看吗********** Lombok 子类如何使用 @Builder

本文分享自微信公众号 - 程序员小乐(study_tech)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Wesley13 Wesley13
3年前
SSH 证书登录教程
点击关注上方“杰哥的IT之旅”,后台回复“Python自动化(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzAwMjg1NjY3Nw%3D%3D%26mid%3D2247491317%26id
Stella981 Stella981
3年前
SpringBoot:切面AOP实现权限校验:实例演示与注解全解
点击上方"后端架构师(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzI5ODI5NDkxMw%3D%3D%26mid%3D2247490920%26idx%3D2%26sn%3D84fa3d94375cac784
Wesley13 Wesley13
3年前
VS Code 的 7 个开源替代品!
点击关注上方“杰哥的IT之旅”,后台回复“Python自动化(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzAwMjg1NjY3Nw%3D%3D%26mid%3D2247491317%26id
Stella981 Stella981
3年前
Docker 入门终极指南:边学边用
点击关注上方“杰哥的IT之旅”,后台回复“Python自动化(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzAwMjg1NjY3Nw%3D%3D%26mid%3D2247491317%26id
Wesley13 Wesley13
3年前
2020年8月程序员工资统计,平均14401元,下跌势头止住了!
点击关注上方“杰哥的IT之旅”,后台回复“Python自动化(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzAwMjg1NjY3Nw%3D%3D%26mid%3D2247491317%26id
Stella981 Stella981
3年前
GitHub 数据告诉你:最幸福的码农在用什么编程语言?
点击关注上方“杰哥的IT之旅”,后台回复“Python自动化(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzAwMjg1NjY3Nw%3D%3D%26mid%3D2247491317%26id
Wesley13 Wesley13
3年前
Java 中的 SPI 机制是到底是什么?高级 Java 必须掌握!
点击上方"程序员小乐(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzI5ODI5NDkxMw%3D%3D%26mid%3D2247490920%26idx%3D2%26sn%3D84fa3d94375cac784
Easter79 Easter79
3年前
SpringCloud开发内存占用过高解决方法
点击上方"程序员小乐(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzI5ODI5NDkxMw%3D%3D%26mid%3D2247490920%26idx%3D2%26sn%3D84fa3d94375cac784