使用Lombok @Singular注解Map后无法获取Builder中的Map变量问题
关于Lombok @Singular修饰Map后Builder中无法获取Map变量的问题
问题原因
当你用@Singular修饰Map类型字段时,Lombok的Builder不会直接在Builder类中维护一个Map实例,而是拆分存储键和值的两个列表(即你看到的params$key和params$value)。这种设计是为了支持逐个添加键值对的流畅API(比如builder.param("key1", "value1").param("key2", "value2")),而非直接传入整个Map。
构造器中获取Map的解决方法
你在自定义构造器里直接访问builder.params失败,是因为Builder类中根本不存在这个字段。如果必须自定义构造器,需要手动将Builder中的键值列表组装成Map:
public WebServiceStatus(WebServiceStatusBuilder builder) { this.wsdl = builder.wsdl; this.operation = builder.operation; // 手动组装Map this.params = new HashMap<>(); for (int i = 0; i < builder.params$key.size(); i++) { this.params.put(builder.params$key.get(i), builder.params$value.get(i)); } }
更推荐的方式是不要自定义构造器,让Lombok自动生成构造逻辑——它会在调用build()方法时自动将两个列表组装成不可变的Map(默认用Guava的ImmutableMap,无Guava则用普通HashMap),避免手动组装的麻烦。
额外问题解答
1. 是否必须自行编写Getter方法?该方案存在问题吗?
不需要自行编写Getter。你的类已经标注@Getter,Lombok会自动为params字段生成getParams()方法,返回的是组装完成的完整Map,而非Builder中的临时列表。
如果自行编写Getter也没有问题,但属于重复劳动,且Lombok生成的Getter默认会返回不可变Map,防止外部修改对象内部状态,手动编写可能遗漏这一点。
2. 为什么Lombok不为@Singular修饰的Map在Builder中生成Getter?
这是@Singular的设计决定:
- Builder的核心是逐步构建对象,
@Singular的目的是提供逐个添加元素的API,内部用拆分的列表存储临时数据是为了高效支持这种操作。 - 如果在Builder中生成
params的Getter,每次调用都需要实时将两个列表组装成Map,会带来不必要的性能开销。 - 暴露Builder内部的Map实现细节,违背了Builder模式封装构建过程的设计初衷。
内容的提问来源于stack exchange,提问作者fvpaz
相关产品推荐
相关产品推荐

