前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >聊聊使用lombok @Builder踩到的坑

聊聊使用lombok @Builder踩到的坑

作者头像
lyb-geek
发布2022-01-07 09:54:47
5120
发布2022-01-07 09:54:47
举报
文章被收录于专栏:Linyb极客之路Linyb极客之路

01

前言

什么是lombok

Lombok项目是一个Java库,它会自动插入编辑器和构建工具中,Lombok提供了一组有用的注释,用来消除Java类中的大量样板代码。

对lombok不熟悉的朋友,可以阅读一下官方文档,再来看本文。官方文档如下

https://projectlombok.org/

02

正文

我们先来看一个小例子

提问: main函数会输出什么?

答案:空指针异常

代码语言:javascript
复制
Exception in thread "main" java.lang.NullPointerException
  at com.github.lybgeek.msg.test.User.addPositionList(User.java:25)
  at com.github.lybgeek.msg.test.User.main(User.java:30)

回答出正确答案的朋友,下文基本上可以不用看了。可能有些朋友会有疑问,我例子中明明使用了

代码语言:javascript
复制
private List<String> positionList = new ArrayList<>();

为什么还会报空指针?

真相就在lombok用@builder生成的class文件中,我们看下使用@builder,生成的class文件反编译后长啥样

看到我圈红起来的,大家应该就一目了然。原来当我们用

代码语言:javascript
复制
User user = User.builder().username("张三").build();

时,此时user对象中的positionList就会被userBuilder中的positionList覆盖,而userBuilder中的positionList是null

03

如何解决

方法一:positionList前面加上final修饰

代码语言:javascript
复制
private final List<String> positionList = new ArrayList<>();

此时用@Budiler生成class为

此时user对象中的positionList用的还是原先的positionList,因此不会出现空指针异常

方法二:positionList前面加上@Builder.Default注解

代码语言:javascript
复制
@Builder.Default
 private List<String> positionList = new ArrayList<>();

此时用@Budiler生成class为

代码语言:javascript
复制
public static class UserBuilder {
        private String username;
        private boolean positionList$set;
        private List<String> positionList;

        UserBuilder() {
        }

        public User.UserBuilder username(final String username) {
            this.username = username;
            return this;
        }

        public User.UserBuilder positionList(final List<String> positionList) {
            this.positionList = positionList;
            this.positionList$set = true;
            return this;
        }

        public User build() {
            List<String> positionList = this.positionList;
            if (!this.positionList$set) {
                positionList = User.$default$positionList();
            }

            return new User(this.username, positionList);
        }

当positionList$set为false,会给userBuilder的positionList赋值为

代码语言:javascript
复制
User.$default$positionList();
即:
  private static List<String> $default$positionList() {
        return new ArrayList();
    }

因此当user对象中的positionList被userBuilder中的positionList覆盖后,userBuilder中的positionList是new ArrayList(),此时就不会出现空指针现象

方法三:不用build实例化对象

代码语言:javascript
复制
User user = User.builder().username("张三").build();

改成用

代码语言:javascript
复制
User user = new User();
user.setUsername("张三");
user.addPositionList("经理");

04

总结

很多时候没那么多的想当然

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-09-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Linyb极客之路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档