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

Posted maohuidong

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了记lombok@Data和@Builder一起用无法添加无参构造方法的坑相关的知识,希望对你有一定的参考价值。

转自:https://blog.csdn.net/w605283073/article/details/89221853

 

今天和小伙伴讨论一个mybatis-plus的一个诡异问题,最后定位到原因竟然是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 */ }
}
}

以上是关于记lombok@Data和@Builder一起用无法添加无参构造方法的坑的主要内容,如果未能解决你的问题,请参考以下文章

Lombok-@Data

lombok @Data注解有没有实现序列化?

@Data 注解作用JavaBean

javajava JSR 269 自定义注解实战 Lombok @Data注解 java版本直接调用

javajava JSR 269 自定义注解实战 Lombok @Data注解

为啥所有 Slider 小部件在 ListView.builder 中一起移动?