轉自: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 */ }
}
}