原创

lombok@Data和@Builder一起用无法添加无参构造方法怎么办

背景

       本人非常喜欢用lombok插件,这个写代码岂一个爽字了的。对于@Builder的链式编程更是爱不释手。但是今天遇到了一个棘手的问题,同时使用了@Data和@Builder后,利用fastjson的parseObject反序列化尽然提示缺少无参构造函数。加上@NoArgsConstructor注解一样不顶用;手动添加无参构造函数一样无济于事。网上说是升级fastjson到一定的版本可以解决此问题。但是我升级到最新的,看过源码感觉是忽悠人的。(gson兼容性这点比fastjson明显要好。)折腾了一番,才有了本文。最后定位到原因竟然是lombok@Data和@Builder一起用无法添加无参构造方法引起的,非常隐蔽。

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

 

单独使用@Data注解,会生成无参数构造方法。


  // 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
    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 */ }
    }
}

完美,收工。

正文到此结束
本文目录