You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Lombok的.build()阶段自动填充BookSummary的summary字段?

问题:用Lombok Builder自动填充字段,同时兼容直接字段访问的优雅实现

我需要在调用.build()方法时,自动给BookSummary类的summary字段赋值,目前是通过自定义构造器实现的,但想找更简洁优雅的写法。

关键限制:部分接收该对象的API会直接读取字段而非访问器方法,比如Gson序列化时,会直接读取summary字段的默认值,不会走重写后的getSummary()方法,所以靠重写get方法这条路走不通。


现有代码结构

父类 Book

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;

@Data
@AllArgsConstructor
@NoArgsConstructor
@SuperBuilder
public class Book
{
    protected String title;
    protected String author;
    protected String description;
}

当前实现的 BookSummary(自定义构造器方式)

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.ToString;
import lombok.experimental.SuperBuilder;

@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@AllArgsConstructor
@NoArgsConstructor
@SuperBuilder
public class BookSummary extends Book
{
    public String summary;

    public BookSummary(BookSummaryBuilder<?, ?> b)
    {
       super(b);
       this.summary = getTitle() + getAuthor() + getDescription();
    }  
}

无效方案示例(重写getSummary()+@Builder.Default)

我试过用@Builder.Default给summary设默认值,同时重写getSummary()方法动态生成内容,但Gson序列化时会直接读取字段值,导致结果完全不符合预期:

public class BookSummary extends Book
{
    @Builder.Default
    public String summary = "xxxxxxxxxxxxxxx";

    public String getSummary()
    {
        return getTitle() + getAuthor() + getDescription();
    }
}

// 测试代码
BookSummary bookSummary = BookSummary.builder()
            .title("Java forever")
            .author("John John")
            .description("bla-bla-bla-bla")
            .build();

String json = new GsonBuilder().create().toJson(bookSummary);

序列化后的JSON结果:

{
    "summary":"xxxxxxxxxxxxxxx",
    "title":"Java forever",
    "author":"John John",
    "description":"bla-bla-bla-bla"
}

优雅解决方案推荐

方案:自定义Builder的build()方法

利用Lombok @SuperBuilder生成的Builder类,重写它的build()方法,在构建实例后直接给summary字段赋值,既简洁又能保证字段被正确填充:

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.ToString;
import lombok.experimental.SuperBuilder;

@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@AllArgsConstructor
@NoArgsConstructor
@SuperBuilder
public class BookSummary extends Book {
    public String summary;

    public static class BookSummaryBuilder<C extends BookSummary, B extends BookSummaryBuilder<C, B>> 
            extends BookBuilder<C, B> {
        
        @Override
        public C build() {
            C instance = super.build();
            // 直接给字段赋值,兼容所有读取字段的场景
            instance.summary = instance.getTitle() + instance.getAuthor() + instance.getDescription();
            return instance;
        }
    }
}

验证效果

用这个方案构建对象后,Gson序列化的结果会是:

{
    "summary":"Java foreverJohn Johnbla-bla-bla-bla",
    "title":"Java forever",
    "author":"John John",
    "description":"bla-bla-bla-bla"
}

完全符合预期,而且代码比自定义构造器更简洁,也更贴合Lombok的设计思路。


内容的提问来源于stack exchange,提问作者VeryNiceArgumentException

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 12:05:19