如何实现带参数的Builder方法?解决ApiRequest构建报错问题
问题分析
报错Expected 0 arguments but found 1的核心原因是混用了Lombok的@Builder注解和手动编写的Builder类,同时手动实现的代码还存在几个关键问题:
- Lombok的@Builder会自动生成名为
Builder的内部类,以及无参的ApiRequest.builder()静态方法,和你手动写的小写builder类冲突。 - 手动编写的
builder类中,构造方法引用了未定义的bucketKey字段,且类名不符合Builder模式的常规命名规范(应为大写Builder)。
正确实现方式
方式一:完全使用Lombok的@Builder(推荐)
如果想用Lombok简化代码,无需手动编写Builder类,只需补充字段并通过自定义静态方法实现带初始参数的builder调用:
@Builder @Getter @Setter public class ApiRequest { private String bucketKey; // 补充你需要的bucketKey字段 private String clientName; // 自定义静态方法,接收bucketKey作为初始参数 public static ApiRequest.ApiRequestBuilder builder(String bucketKey) { return ApiRequest.builder().bucketKey(bucketKey); } }
调用方式保持你原来的写法即可:
ApiRequest request = ApiRequest.builder("test 55").clientName(SERVICE).build();
方式二:手动实现Builder模式(不依赖Lombok)
如果不想用Lombok,手动实现标准Builder模式,注意类名、构造方法和字段的一致性:
@Getter @Setter public class ApiRequest { private String bucketKey; private String clientName; // 私有构造方法,强制通过Builder创建实例 private ApiRequest(Builder builder) { this.bucketKey = builder.bucketKey; this.clientName = builder.clientName; } // 静态方法获取Builder实例 public static Builder builder(String bucketKey) { return new Builder(bucketKey); } // 标准Builder内部类(大写开头) public static class Builder { private String bucketKey; private String clientName; // 构造方法初始化bucketKey public Builder(String bucketKey) { this.bucketKey = bucketKey; } // 链式设置clientName public Builder clientName(String clientName) { this.clientName = clientName; return this; } // 构建ApiRequest实例 public ApiRequest build() { return new ApiRequest(this); } } }
调用方式不变:
ApiRequest request = ApiRequest.builder("test 55").clientName(SERVICE).build();
关键注意点
- 禁止同时使用Lombok的@Builder和手动编写Builder类,避免代码冲突。
- Builder模式的内部类名通常为大写
Builder,静态工厂方法名一般为builder,遵循通用命名规范。 - 手动实现时,实体类构造方法设为私有,避免直接创建实例,强制通过Builder完成对象构建。
内容的提问来源于stack exchange,提问作者Peter Penzov
相关产品推荐
相关产品推荐

