Java中抽象类配合递归泛型Builder模式的核心是:抽象Builder声明通用步骤并用T extends Builder<T>保证链式调用类型安全,子类实现self()返回自身类型,从而支持复用与多态扩展。

Java中用抽象类配合Builder模式构建复杂泛型对象,核心在于:**让抽象Builder声明通用构建步骤,同时通过递归泛型(T extends Builder<T>)保证链式调用类型安全,再由子类实现具体逻辑并返回自身类型**。这种方式既复用骨架,又支持多态扩展,特别适合有继承体系的复杂对象(比如不同类型的Pizza、Report、Config等)。
抽象Builder必须带递归泛型声明
不能只写 abstract class Builder,而要写成:
abstract static class Builder<T extends Builder<T>> {
// 构建逻辑字段(如 toppings, name, timeout 等)
protected String name;
// 链式方法必须返回 T,不是 Builder 或 void
public T setName(String name) {
this.name = name;
return self(); // 关键:靠子类实现 self() 返回具体类型
}
// 抽象方法,强制子类提供“返回自己”的能力
protected abstract T self();
// build 方法返回最终产品,通常为抽象类或接口
public abstract Product build();
}
这样设计后,子类调用 setName(...).setAge(...).build() 才不会中断链式调用,也不会丢失类型信息。
具体子类实现 self() 并完成 build
子类需继承抽象Builder,并明确指定泛型参数为自己类型:
立即学习“Java免费学习笔记(深入)”;
- 声明为
static class UserBuilder extends Builder<UserBuilder> - 重写
self()方法直接return this - 重写
build()方法,构造并返回具体产品(如new User()),同时把 builder 中的字段复制过去
示例片段:
public static class UserBuilder extends Builder<UserBuilder> {
private int age;
public UserBuilder setAge(int age) {
this.age = age;
return self();
}
@Override
protected UserBuilder self() {
return this;
}
@Override
public User build() {
User user = new User();
user.setName(this.name);
user.setAge(this.age);
return user;
}
}
产品类需预留受保护构造,配合 builder 初始化
为防止外部绕过Builder直接 new,产品类应设私有/受保护构造器,并允许 Builder 子类访问:
- Product 类构造器设为
protected(若 Builder 是其内部类,则可设为private) - Builder 子类在
build()中调用该构造器,或通过 setter 赋值 - 若产品有不可变字段,推荐用构造器注入;若需灵活赋值,setter 更方便
例如:
public class User {
private final String name;
private final int age;
protected User(String name, int age) {
this.name = name;
this.age = age;
}
// 可选:提供 Builder 内部使用的无参构造 + setter(用于非 final 字段)
}
客户端调用简洁且类型安全
使用时完全感知不到泛型细节,写法自然:
User user = new UserBuilder()
.setName("Alice")
.setAge(30)
.build();
如果后续新增 AdminBuilder extends Builder<AdminBuilder>,它也能复用同一套抽象定义,同时保持自己的专属字段和验证逻辑,不影响原有代码。
不复杂但容易忽略:递归泛型 + self() 是让链式调用不“断链”的关键,缺一不可。


















