记录一次@Data和@Builder导致无参构造函数失效问题

说在前边

这个问题发生在接口联调的时候,本地在idea测试没有问题,但是发到测试环境使用postman进行测试就出问题,做一个记录防止再犯,也希望可以帮助到其他的同志们。

现象

用postman请求接口时报出了序列化异常,错误信息很长基本上都是乱码,这里就不贴出来了,提示关键信息,no Creators, like default construct, exist。主要原因是因为请求接口的入参对象没有默认构造函数导致,可以看下你的是否是这样的原因呢?那么为什么会导致这样的结果呢,我们继续一步一步往下走,入参的实体对象使用了@Data和@Builder进行注解。

@Data
@Builder
public class TestBuilder {

    private String name;

    private Integer age;

    public void start() {
        System.out.println("这是开始");
    }

    public void end() {
        System.out.println("这是结束");
    }
}

经常使用lombok的同志们都知道,@Data已经包含了构造函数和set、get、equals、hashCode、canEqual、和toString,这个可以从字节码文件中看出来,如下图
在这里插入图片描述
但是为什么和@Builder一起使用后则默认的无参构造没有呢,我们看下增加了@Builder后的字节码信息
在这里插入图片描述
可以看到增加了一个带参的构造函数和一个builder()方法,在target目录下找到实体类的class文件,文件中并没有一处实现了该实体了的无参构造函数,这里贴关键代码,其中会有这样的两段代码

  1. builder()方法
public static TestBuilderBuilder builder() {
        return new TestBuilderBuilder();
    }

2.静态内部类

public static class TestBuilderBuilder {
        private String name;
        private Integer age;

        TestBuilderBuilder() {
        }

        public TestBuilderBuilder name(final String name) {
            this.name = name;
            return this;
        }

        public TestBuilderBuilder age(final Integer age) {
            this.age = age;
            return this;
        }

        public TestBuilder build() {
            return new TestBuilder(this.name, this.age);
        }

        public String toString() {
            return "TestBuilder.TestBuilderBuilder(name=" + this.name + ", age=" + this.age + ")";
        }
    }

可以看到在静态内部类中build()方法直接创建了一个全部参数的构造,所以在@Data和@Builder同时使用时会出现无参构造不存在的现象。那么该如何解决这一问题呢?

解决方法

有其他的同志们给出的解决方法有增加构造函数,或者使用@Tolerate注解,这里解释一下@Tolerate这个注解是做什么的,引用官方文档的描述:放置任何方法或构造函数以使 lombok 假装它不存在,即生成一个方法,否则该方法会由于可能的冲突而被跳过。lombok官方API文档:https://projectlombok.org/api/。话说回来,我们看下两种解决方式有什么不同的

第一种,增加@NoArgsConstructor@AllArgsConstructor 两个注解

很直白,从字节码文件中可以看出这两个注解会帮助我们直接生成两个构造函数,如图在这里插入图片描述

第二种,写一个无参构造增加@Tolerate注解

这里只是又帮我们增加了一个无参构造
在这里插入图片描述
两者并没有很大的区别,使用哪种全看同志们自己的选择,可以根据一些情况来判断,比如说需要在构造函数中进行一些初始化数据操作,那么就可以采用第二种。

结束在后边

今天的分享到这里结束了,希望可以让其他同志们采坑。
再次声明,以上内容仅是笔者个人理解绝无抄袭他人,有理解不当之处还请同志们多多指点,互相交流

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

树旁有只安静的猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值