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

@Builder的一个坑

作者头像
灬沙师弟
发布2023-11-07 12:47:17
2790
发布2023-11-07 12:47:17
举报
文章被收录于专栏:Java面试教程

背景

最近遇到了一个使用@Builder注解导致线上报NPE的问题。原因在给一个用@Builder注解的Java Bean的一个属性赋默认值之后,使用build方式构建出来的对象该属性的值是null。

本地模拟

在本地创建一个User类,给vip赋上默认值true。并写了一个测试用例,判断vip是否是null。

代码语言:javascript
复制
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
 public class User {
    private Long id;
    private Boolean vip = true;
 }
 
@Test
public void buildTest(){
    User user = User.builder().id(1L).build();
    assertNull(user.getVip());
}

测试用例可以跑过,说明User的vip并没有赋默认值。这是为什么呢?打开User.class反编译之后的文件可以看到,@Builder注解的作用其实就是帮程序员免去写构造者模式的麻烦,内部生成一个UserBuilder静态内部类。当调用build函数的时候,创建对象。由于生成的代码中,没有给vip字段赋默认值自然拿到的是null。

代码语言:javascript
复制
.....省略部分代码......
 public static class UserBuilder {
        private Long id;
        private Boolean vip;

        UserBuilder() {
        }

        public UserBuilder id(final Long id) {
            this.id = id;
            return this;
        }

        public UserBuilder vip(final Boolean vip) {
            this.vip = vip;
            return this;
        }

        public User build() {
            return new User(this.id, this.vip);
        }

        public String toString() {
            return "User.UserBuilder(id=" + this.id + ", vip=" + this.vip + ")";
        }
    }

解决办法

解决办法也很简单,不需要我们重写User的建造者模式,只要在赋默认值的属性上加上@Builder.Default注解就可以了。

代码语言:javascript
复制
@Data
@Builder
public class User {
    private Long id;
    @Builder.Default
    private Boolean vip = true;
}

再反编译User.class文件文件,发现生成了一个静态方法defaultvip(),该方法返回的就是vip的默认值。调用build方法时会判断vip是否已经设置,没有设置则调用defaultvip()方法赋值。

代码语言:javascript
复制
public class User {
    private Long id;
    private Boolean vip;

    private static Boolean $default$vip() {
        return true;
    }
      public static class UserBuilder {
       ..

        public User build() {
            Boolean vip$value = this.vip$value;
            if (!this.vip$set) {
                vip$value = User.$default$vip();
            }

            return new User(this.id, vip$value);
        }
    }
}      

总结

Lombok虽然可以帮程序员自己去写很多代码,但是lombok自动生成的代码毕竟不可控,需要我们在实际开发中去探究他实际生成的代码是否满足我们的要求,这样才能避免下次踩坑。

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

本文分享自 Java面试教程 微信公众号,前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
  • 本地模拟
  • 解决办法
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档