lombok 插件使用注意事项

为了更简洁的构造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,一经查实,本站将立刻删除。
(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022年6月11日 10:52
下一篇 2022年6月11日 13:11

相关推荐

发表评论

您的电子邮箱地址不会被公开。