为了更简洁的构造bean对象,使用注解@Builder,然而发现,通过builder生成的bean对象,字段默认值没了(备注:日常开发中,bean 的成员变量尽量使用封装对象,以及尽量不要有默认值),但是通过new 得到的对象,字段默认值存在。
问题伪代码如下:
/**
* @description: 用户父类
* @author: lyl
* @create: 2022-06-01 14:42:27
**/
@Data
public class UserParent {
/**
* id
*/
private String id;
}
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UserChildren extends UserParent{
/**
* 姓名
*/
private String name = "七夜";
/**
* 年龄
*/
private Integer age;
}
@SpringBootTest
class CodeTestApplicationTests {
@Test
void contextLoads() {
UserChildren user1 = new UserChildren();
System.out.println(user1);
UserChildren user2 = UserChildren.builder().build();
System.out.println(user2);
}
}
执行结果如下:
UserChildren(name=七夜, age=null)
UserChildren(name=null, age=null)
针对lombok注解问题的排查,最简单的方式就是直接查看编译之后的代码。反编译后的UserCildren.class如下:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package com.yalin.code.vo;
public class UserChildren extends UserParent {
private String name = "七夜";
private Integer age;
public static UserChildrenBuilder builder() {
return new UserChildrenBuilder();
}
public String getName() {
return this.name;
}
public Integer getAge() {
return this.age;
}
public void setName(final String name) {
this.name = name;
}
public void setAge(final Integer age) {
this.age = age;
}
public boolean equals(final Object o) {
if (o == this) {
return true;
} else if (!(o instanceof UserChildren)) {
return false;
} else {
UserChildren other = (UserChildren)o;
if (!other.canEqual(this)) {
return false;
} else {
Object this$age = this.getAge();
Object other$age = other.getAge();
if (this$age == null) {
if (other$age != null) {
return false;
}
} else if (!this$age.equals(other$age)) {
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;
}
return true;
}
}
}
protected boolean canEqual(final Object other) {
return other instanceof UserChildren;
}
public int hashCode() {
int PRIME = true;
int result = 1;
Object $age = this.getAge();
result = result * 59 + ($age == null ? 43 : $age.hashCode());
Object $name = this.getName();
result = result * 59 + ($name == null ? 43 : $name.hashCode());
return result;
}
public String toString() {
String var10000 = this.getName();
return "UserChildren(name=" + var10000 + ", age=" + this.getAge() + ")";
}
public UserChildren() {
}
public UserChildren(final String name, final Integer age) {
this.name = name;
this.age = age;
}
public static class UserChildrenBuilder {
private String name;
private Integer age;
UserChildrenBuilder() {
}
public UserChildrenBuilder name(final String name) {
this.name = name;
return this;
}
public UserChildrenBuilder age(final Integer age) {
this.age = age;
return this;
}
public UserChildren build() {
return new UserChildren(this.name, this.age);
}
public String toString() {
return "UserChildren.UserChildrenBuilder(name=" + this.name + ", age=" + this.age + ")";
}
}
}
通过查看编译之后的代码,可以看到,使用@Builder注解之后,lombok会生成一个UserChildrenBuilder的静态内部类,这个类包含了UserChildren的成员变量,但是包含的成员变量中,name字段的初始值没了,当我们使用UserChildren.builder().build()来构造bean时,代码内部先生成一个UserChildrenBuilder的对象,然后对这个对象进行赋值,最后调用UserChildren的全参构造函数,生成UserChildren对象。就像一个代理一样!
因此:
使用new 对象时,没有使用到UserChildrenBuilder,因此name字段的初始值保留了。
使用builder构造对象时,UserChildrenBuilder的name字段没有了初始值,生成的对象,name字段自然就没值了。
本文链接:https://www.dzdvip.com/33843.html
版权声明:本文内容均来源于互联网。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 395045033@qq.com,一经查实,本站将立刻删除。