要实现父子类都能链式调用的泛型构建者模式,核心是使用f-bound类型参数:父类person

要实现父子类都能链式调用的泛型构建者模式(Generic Builder),核心是让子类构建者能返回自身类型,而不是父类构建者,避免类型擦除导致的链式中断。关键在于使用“F-bound type parameter”(自引用泛型)配合递归泛型定义。
父类构建者声明:用泛型参数绑定自身
父类 Person 及其构建者不直接写死返回类型,而是把构建者类型作为泛型参数传入,让子类能“回填”自己的构建者类型:
- 父类定义:
class Person<b extends person.builder>></b> - 构建者声明为抽象静态类,并带相同泛型参数:
abstract static class Builder<b extends builder>></b> - 所有 setter 方法返回
B(即具体子类构建者),而非Builder
子类构建者继承并“回填”自身类型
子类(如 Student)继承父类时,显式将自身构建者类型传给父类泛型参数;其构建者继承父构建者,并把泛型参数设为自身:
class Student extends Person<student.builder></student.builder>static class Builder extends Person.Builder<builder></builder>- 这样
name("Alice").grade(95)中,name()返回Builder,后续可继续调用子类特有方法
关键细节:避免类型丢失和编译错误
常见坑点及解法:
- 构造器中必须调用
self()—— 父构建者里定义一个抽象方法protected abstract B self();,子构建者覆写为return (B) this; - 所有 setter 必须以
return self();结尾,保证返回的是当前构建者实例(而非父类类型) - 不要在父构建者中 new 子类实例;构建逻辑由子类
build()实现,父类build()应为protected abstract T build();
完整最小示例(可直接运行)
以下代码体现父子链式调用:new Student.Builder().name("Tom").age(20).grade(88).build(); —— 全程不打断、类型安全、IDE 可提示子类方法:
// 父类
class Person<b extends person.builder>> {
protected String name;
protected int age;
public static abstract class Builder<b extends builder>> {
protected String name;
protected int age;
protected abstract B self();
public B name(String name) { this.name = name; return self(); }
public B age(int age) { this.age = age; return self(); }
public abstract Person<b> build();
}
}
// 子类
class Student extends Person<student.builder private int grade public static class builder extends person.builder protected self return this this.grade="grade;" student build s="new" s.name="this.name;" s.age="this.age;" s.grade="this.grade;"></student.builder></b></b></b>Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











