记lombok@Data和@Builder一起用无法添加无参构造方法的坑

 作者:明明如月学长, CSDN 博客专家,蚂蚁集团高级 Java 工程师,《性能优化方法论》作者、《解锁大厂思维:剖析《阿里巴巴Java开发手册》》、《再学经典:《EffectiveJava》独家解析》专栏作者。

热门文章推荐
(1)《人工智能时代,软件工程师们将会被取代?》
(2)《超全人工智能 AI工具导航网站合集》
(3)《如何写出高质量的文章:从战略到战术》
(4)《什么? 你还没用过 Cursor? 智能 AI 代码生成工具 Cursor 安装和使用介绍》
(5)《我的性能方法论》
(6)《无需魔法打开即用的 AI 工具集锦》

一、结论先行

手写默认构造方法,然后加上 @Tolerate 注解即可。

@Builder
@Data
public class Dog {

    private String name;

    private Integer age;

    private String nickName;

    private String test;

    @Tolerate
   public Dog() {}
}

二、详情(感兴趣继续看)

今天和小伙伴讨论一个mybatis-plus的一个诡异问题,最后定位到原因竟然是lombok@Data和@Builder一起用无法添加无参构造方法引起的,非常隐蔽。

很多框架都是同反射等调用无参数构造方法来创建实例的,需要注意。

单独使用@Data注解,编译后的类文件会生成无参数构造方法(这并不是@Data提供的特性,而是Java自带的特性)。


  // IntelliJ API Decompiler stub source generated from a class file
  // Implementation of methods is not available

package com.chujianyun.util;

public class Dog {
    private java.lang.String name;
    private java.lang.Integer age;
    private java.lang.String nickName;
    private java.lang.String test;

    public Dog() { /* compiled code */ }

    public java.lang.String getName() { /* compiled code */ }

    public java.lang.Integer getAge() { /* compiled code */ }

    public java.lang.String getNickName() { /* compiled code */ }

    public java.lang.String getTest() { /* compiled code */ }

    public void setName(java.lang.String name) { /* compiled code */ }

    public void setAge(java.lang.Integer age) { /* compiled code */ }

    public void setNickName(java.lang.String nickName) { /* compiled code */ }

    public void setTest(java.lang.String test) { /* compiled code */ }

    public boolean equals(java.lang.Object o) { /* compiled code */ }

    protected boolean canEqual(java.lang.Object other) { /* compiled code */ }

    public int hashCode() { /* compiled code */ }

    public java.lang.String toString() { /* compiled code */ }
}

单独使用@Builder注解,发现生成了全属性的构造方法。

package com.chujianyun.util;

public class Dog {
    private java.lang.String name;
    private java.lang.Integer age;
    private java.lang.String nickName;
    private java.lang.String test;

    Dog(java.lang.String name, java.lang.Integer age, java.lang.String nickName, java.lang.String test) { /* compiled code */ }

    public static com.chujianyun.util.Dog.DogBuilder builder() { /* compiled code */ }

    public static class DogBuilder {
        private java.lang.String name;
        private java.lang.Integer age;
        private java.lang.String nickName;
        private java.lang.String test;

        DogBuilder() { /* compiled code */ }

        public com.chujianyun.util.Dog.DogBuilder name(java.lang.String name) { /* compiled code */ }

        public com.chujianyun.util.Dog.DogBuilder age(java.lang.Integer age) { /* compiled code */ }

        public com.chujianyun.util.Dog.DogBuilder nickName(java.lang.String nickName) { /* compiled code */ }

        public com.chujianyun.util.Dog.DogBuilder test(java.lang.String test) { /* compiled code */ }

        public com.chujianyun.util.Dog build() { /* compiled code */ }

        public java.lang.String toString() { /* compiled code */ }
    }
}

@Data和@Builder一起用

@Data
@Builder
public class Dog {

    private String name;

    private Integer age;

    private String nickName;

    private String test;

}

效果


  // IntelliJ API Decompiler stub source generated from a class file
  // Implementation of methods is not available

package com.chujianyun.util;

public class Dog {
    private java.lang.String name;
    private java.lang.Integer age;
    private java.lang.String nickName;
    private java.lang.String test;

    Dog(java.lang.String name, java.lang.Integer age, java.lang.String nickName, java.lang.String test) { /* compiled code */ }

    public static com.chujianyun.util.Dog.DogBuilder builder() { /* compiled code */ }

    public java.lang.String getName() { /* compiled code */ }

    public java.lang.Integer getAge() { /* compiled code */ }

    public java.lang.String getNickName() { /* compiled code */ }

    public java.lang.String getTest() { /* compiled code */ }

    public void setName(java.lang.String name) { /* compiled code */ }

    public void setAge(java.lang.Integer age) { /* compiled code */ }

    public void setNickName(java.lang.String nickName) { /* compiled code */ }

    public void setTest(java.lang.String test) { /* compiled code */ }

    public boolean equals(java.lang.Object o) { /* compiled code */ }

    protected boolean canEqual(java.lang.Object other) { /* compiled code */ }

    public int hashCode() { /* compiled code */ }

    public java.lang.String toString() { /* compiled code */ }

    public static class DogBuilder {
        private java.lang.String name;
        private java.lang.Integer age;
        private java.lang.String nickName;
        private java.lang.String test;

        DogBuilder() { /* compiled code */ }

        public com.chujianyun.util.Dog.DogBuilder name(java.lang.String name) { /* compiled code */ }

        public com.chujianyun.util.Dog.DogBuilder age(java.lang.Integer age) { /* compiled code */ }

        public com.chujianyun.util.Dog.DogBuilder nickName(java.lang.String nickName) { /* compiled code */ }

        public com.chujianyun.util.Dog.DogBuilder test(java.lang.String test) { /* compiled code */ }

        public com.chujianyun.util.Dog build() { /* compiled code */ }

        public java.lang.String toString() { /* compiled code */ }
    }
}

我们发现外层的Dog类没有了默认的构造方法。

如果手动添加无参数构造方法或者用@NoArgsConstructor注解都会报错!

@Builder
@Data
@NoArgsConstructor
public class Dog {

    private String name;

    private Integer age;

    private String nickName;

    private String test;

}

正确写法如下:

@Builder
@Data
public class Dog {

    private String name;

    private Integer age;

    private String nickName;

    private String test;

    @Tolerate
   public Dog() {}
}

解释如下

添加函数或者构造方法,让lombok假装它不存在(不感知)。

效果如下:

package com.chujianyun.util;

public class Dog {
    private java.lang.String name;
    private java.lang.Integer age;
    private java.lang.String nickName;
    private java.lang.String test;

    Dog() { /* compiled code */ }

    Dog(java.lang.String name, java.lang.Integer age, java.lang.String nickName, java.lang.String test) { /* compiled code */ }

    public static com.chujianyun.util.Dog.DogBuilder builder() { /* compiled code */ }

    public java.lang.String getName() { /* compiled code */ }

    public java.lang.Integer getAge() { /* compiled code */ }

    public java.lang.String getNickName() { /* compiled code */ }

    public java.lang.String getTest() { /* compiled code */ }

    public void setName(java.lang.String name) { /* compiled code */ }

    public void setAge(java.lang.Integer age) { /* compiled code */ }

    public void setNickName(java.lang.String nickName) { /* compiled code */ }

    public void setTest(java.lang.String test) { /* compiled code */ }

    public boolean equals(java.lang.Object o) { /* compiled code */ }

    protected boolean canEqual(java.lang.Object other) { /* compiled code */ }

    public int hashCode() { /* compiled code */ }

    public java.lang.String toString() { /* compiled code */ }

    public static class DogBuilder {
        private java.lang.String name;
        private java.lang.Integer age;
        private java.lang.String nickName;
        private java.lang.String test;

        DogBuilder() { /* compiled code */ }

        public com.chujianyun.util.Dog.DogBuilder name(java.lang.String name) { /* compiled code */ }

        public com.chujianyun.util.Dog.DogBuilder age(java.lang.Integer age) { /* compiled code */ }

        public com.chujianyun.util.Dog.DogBuilder nickName(java.lang.String nickName) { /* compiled code */ }

        public com.chujianyun.util.Dog.DogBuilder test(java.lang.String test) { /* compiled code */ }

        public com.chujianyun.util.Dog build() { /* compiled code */ }

        public java.lang.String toString() { /* compiled code */ }
    }
}

完美,手工。。。

欢迎加入我的知识星球,知识星球ID:15165241 一起交流学习。
https://t.zsxq.com/Z3bAiea,申请时标注来自CSDN。

欢迎加入我们的 slack 工作区,在里面可以对ai 和我进行提问。
https://join.slack.com/t/ai-yx51081/shared_invite/zt-1t8cp1lk3-ZMAFutZcN3PCW~8WQDGjPg

  • 44
    点赞
  • 55
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 19
    评论
评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

明明如月学长

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

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

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

打赏作者

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

抵扣说明:

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

余额充值