1.问题
实体类使用@lombok.Builder注解和自己手动编写的全参构造方法,构建实体类实例时部分字段值发生了错乱。
2.示例代码
/**
* @ClassName Demo
* @Description TODO
* @Author Mr Zhang
* @Date 2020/9/16 13:48
* @Version 1.0
**/
@lombok.Builder
@lombok.Data
public class Demo {
private Long id;
private String name;
private String password;
private String nickname;
private String headImageUrl;
public Demo() {
}
//手动编码的构造方法
public Demo(Long id, String name, String nickname, String password, String headImageUrl) {
this.id = id;
this.name = name;
this.password = password;
this.nickname = nickname;
this.headImageUrl = headImageUrl;
}
}
class DemoTest{
public static void main(String[] args) {
Demo demo = Demo.builder().id(1L).name("demo").password("password").nickname("nickname").headImageUrl("headImageUrl").build();
System.out.println(demo);
}
}
结果
预期结果:
Demo(id=1, name=demo, password=password, nickname=nickname, headImageUrl=headImageUrl)
实际结果:
Demo(id=1, name=demo, password=nickname, nickname=password, headImageUrl=headImageUrl)
结果说明:
赋值时Demo的password值为password,nickname值为nickname;输出结果时password值和nickname值发生了错乱
编译后的代码
public class Demo {
private Long id;
private String name;
private String password;
private String nickname;
private String headImageUrl;
public Demo() {
}
public Demo(Long id, String name, String nickname, String password, String headImageUrl) {
this.id = id;
this.name = name;
this.password = password;
this.nickname = nickname;
this.headImageUrl = headImageUrl;
}
public static Demo.DemoBuilder builder() {
return new Demo.DemoBuilder();
}
public Long getId() {
return this.id;
}
public String getName() {
return this.name;
}
public String getPassword() {
return this.password;
}
public String getNickname() {
return this.nickname;
}
public String getHeadImageUrl() {
return this.headImageUrl;
}
public void setId(Long id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setPassword(String password) {
this.password = password;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public void setHeadImageUrl(String headImageUrl) {
this.headImageUrl = headImageUrl;
}
public boolean equals(Object o) {
if (o == this) {
return true;
} else if (!(o instanceof Demo)) {
return false;
} else {
Demo other = (Demo)o;
if (!other.canEqual(this)) {
return false;
} else {
label71: {
Object this$id = this.getId();
Object other$id = other.getId();
if (this$id == null) {
if (other$id == null) {
break label71;
}
} else if (this$id.equals(other$id)) {
break label71;
}
return false;
}
Object this$name = this.getName();
Object other$name = other.getName();
if (this$name == null) {
if (other$name != null) {
return false;
}
} else if (!this$name.equals(other$name)) {
return false;
}
label57: {
Object this$password = this.getPassword();
Object other$password = other.getPassword();
if (this$password == null) {
if (other$password == null) {
break label57;
}
} else if (this$password.equals(other$password)) {
break label57;
}
return false;
}
Object this$nickname = this.getNickname();
Object other$nickname = other.getNickname();
if (this$nickname == null) {
if (other$nickname != null) {
return false;
}
} else if (!this$nickname.equals(other$nickname)) {
return false;
}
Object this$headImageUrl = this.getHeadImageUrl();
Object other$headImageUrl = other.getHeadImageUrl();
if (this$headImageUrl == null) {
if (other$headImageUrl == null) {
return true;
}
} else if (this$headImageUrl.equals(other$headImageUrl)) {
return true;
}
return false;
}
}
}
protected boolean canEqual(Object other) {
return other instanceof Demo;
}
public int hashCode() {
int PRIME = true;
int result = 1;
Object $id = this.getId();
int result = result * 59 + ($id == null ? 43 : $id.hashCode());
Object $name = this.getName();
result = result * 59 + ($name == null ? 43 : $name.hashCode());
Object $password = this.getPassword();
result = result * 59 + ($password == null ? 43 : $password.hashCode());
Object $nickname = this.getNickname();
result = result * 59 + ($nickname == null ? 43 : $nickname.hashCode());
Object $headImageUrl = this.getHeadImageUrl();
result = result * 59 + ($headImageUrl == null ? 43 : $headImageUrl.hashCode());
return result;
}
public String toString() {
return "Demo(id=" + this.getId() + ", name=" + this.getName() + ", password=" + this.getPassword() + ", nickname=" + this.getNickname() + ", headImageUrl=" + this.getHeadImageUrl() + ")";
}
public static class DemoBuilder {
private Long id;
private String name;
private String password;
private String nickname;
private String headImageUrl;
DemoBuilder() {
}
public Demo.DemoBuilder id(Long id) {
this.id = id;
return this;
}
public Demo.DemoBuilder name(String name) {
this.name = name;
return this;
}
public Demo.DemoBuilder password(String password) {
this.password = password;
return this;
}
public Demo.DemoBuilder nickname(String nickname) {
this.nickname = nickname;
return this;
}
public Demo.DemoBuilder headImageUrl(String headImageUrl) {
this.headImageUrl = headImageUrl;
return this;
}
public Demo build() {
return new Demo(this.id, this.name, this.password, this.nickname, this.headImageUrl);
}
public String toString() {
return "Demo.DemoBuilder(id=" + this.id + ", name=" + this.name + ", password=" + this.password + ", nickname=" + this.nickname + ", headImageUrl=" + this.headImageUrl + ")";
}
}
}
分析
由于@lombok.Builder注解会自动生成一个静态内部类DemoBuilder,静态内部类中的build方法会创建Demo实例对象,此处构建实例对象使用的构造方法是按照字段定义顺序生成的全参构造方法new Demo(this.id, this.name, this.password, this.nickname, this.headImageUrl),而Demo类内实际的全参构造方法public Demo(Long id, String name, String nickname, String password, String headImageUrl) 参数顺序是与属性定义顺序不同的,所以赋值时发生了错乱。