lombok @Builder 注解的用法

Posted 魏晓蕾

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了lombok @Builder 注解的用法相关的知识,希望对你有一定的参考价值。

  • 类声明:
@Builder
public class Person 
    private int id;
    private String name;
    private boolean sex;

  • 类创建:
Person person = Person.builder().id(10).name("abc").sex(true).build();
  • 优点:
  1. 不需写太多的set方法来定义属性内容
  2. 写法更优雅
  • @Builder对类做了什么?

我们可以反编译生成的 Person.class 看下:

public class Person 
    private int id;
    private String name;
    private boolean sex;

    Person(int id, String name, boolean sex) 
        this.id = id;
        this.name = name;
        this.sex = sex;
    

    public static Person.PersonBuilder builder() 
        return new Person.PersonBuilder();
    

    public static class PersonBuilder 
        private int id;
        private String name;
        private boolean sex;

        PersonBuilder() 
        

        public Person.PersonBuilder id(int id) 
            this.id = id;
            return this;
        

        public Person.PersonBuilder name(String name) 
            this.name = name;
            return this;
        

        public Person.PersonBuilder sex(boolean sex) 
            this.sex = sex;
            return this;
        

        public Person build() 
            return new Person(this.id, this.name, this.sex);
        

        public String toString() 
            return "Person.PersonBuilder(id=" + this.id + ", name=" + this.name + ", sex=" + this.sex + ")";
        
    

可以看到,注解在编译后使得Person类中多了一个名为Person.PersonBuilder的静态内部类。这个静态类拥有和Person类相同的属性,并且额外实现了一些方法:
(1)name、sex、id等的属性方法,这些方法和setAttribute十分类似,只是额外返回了实例本身,这使得它可以使用类似于链式调用的写法。
(2)build方法,该方法调用Card类的全参构造方法来生成Person实例。
Card类实现了builder方法,这个方法生成一个空的Person.PersonBuilder实例。

  • 缺点

最明显的一点,在生成Person实例之前,实际上是先创建了一个Person.PersonBuilder实例,这样很明显额外占用了内存。

  • @Builder(toBuilder = true)

这个选项允许你用一个实例化好的Card实例来生成新的Card实例。

public Person.PersonBuilder toBuilder() 
    return (new Person.PersonBuilder()).id(this.id).name(this.name).sex(this.sex);

可以看到,toBuilder方法用当前实例的属性构造了一个新的Builder实例。

  • 需要注意的问题

仔细看会发现此时并没有生成无参构造,一些框架序列化喜欢用反射new对象,比如现在比较流行的序列化框架Fastjson,这时候就会报错,而反射new对象在编译期是发现不了的,所以容易导致线上问题。此时有几种解决方式
(1)同时加上无参和有参的注解,让对象同时生成有参和无参方法(推荐)

@AllArgsConstructor
@NoArgsConstructor

(2)自己写无参构造,加上@Tolerate注解让lombok忽略它(这种写法不推荐,ide程序会无法识别出全参构造,导致写全参构造的时候代码标红)

@Getter
@Setter
@Builder
public class Person 

    private int id;
    private String name;
    private boolean sex;

    @Tolerate
    Person() 
    

所以,使用@Builder的时候,最好和@AllArgsConstructor,@NoArgsConstructor,@Data一起使用。

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Person implements Serializable 
    private int id;
    private String name;
    private boolean sex;

以上是关于lombok @Builder 注解的用法的主要内容,如果未能解决你的问题,请参考以下文章

使用Lombok @Builder注解导致默认值无效

idea怎么看lombok注解自动生成的代码?

lombok中的@Builder.Default注解

Lombok中的@Builder注解的使用

lombok @Builder注解

学习笔记lombok的@Builder注解