Java中如何通过通用接口复用Functional Builder的with方法?
解决Functional Builder接口复用的返回类型问题
问题描述
我为ComponentStatus类实现了一个Functional Builder,使用方式如下:
new ComponentStatus.Builder() .with($ -> { $.name = element.getName(); $.state = element.getState(); $.status = element.getStatus(); $.description = element.getStatusDescription(); }).build();
对应的类代码:
public class ComponentStatus { private final String name; private final int state; private final int status; private final String description; ComponentStatus(String name, int state, int status, String description) { this.name = name; this.state = state; this.status = status; this.description = description; } public static class Builder { public String name; public int state; public int status; public String description; Builder with( Consumer<Builder> builderFunction) { builderFunction.accept(this); return this; } ComponentStatus build() { return new ComponentStatus(name, state, status, description); } } }
该Builder可以正常工作,但现在需要为其他类添加Builder,由于with()方法的逻辑完全相同,我尝试创建一个接口来减少样板代码:
public interface Buildable { default Buildable with( Consumer<Buildable> builderFunction) { builderFunction.accept(this); return this; } Object build(); }
但这个接口无法正常工作,因为with()方法返回的是Buildable而非具体的Builder子类,修改返回类型为<? extends Buildable>也无法解决问题,请问该如何处理?
解决方案
使用**自限定泛型(Self-bounded Generic)**改造Buildable接口,让with()方法返回具体的实现类类型,而非顶层接口类型:
改造后的Buildable接口
public interface Buildable<T extends Buildable<T>> { default T with(Consumer<T> builderFunction) { builderFunction.accept((T) this); return (T) this; } Object build(); }
改造Builder类
让具体的Builder实现该泛型接口,并将自身作为泛型参数传入,同时重写build()方法返回对应实体类:
public class ComponentStatus { // 原有实体类代码不变 private final String name; private final int state; private final int status; private final String description; ComponentStatus(String name, int state, int status, String description) { this.name = name; this.state = state; this.status = status; this.description = description; } public static class Builder implements Buildable<Builder> { public String name; public int state; public int status; public String description; @Override public ComponentStatus build() { return new ComponentStatus(name, state, status, description); } } }
效果说明
改造后,with()方法会返回具体的Builder类型,既保留了链式调用的能力,又能在lambda表达式中直接访问Builder的字段,完全复用了with()方法的逻辑,无需每个Builder重复实现该方法。同时build()方法返回具体的实体类类型,避免了强转操作。
核心原理
自限定泛型T extends Buildable<T>确保泛型参数T既是Buildable的子类,又是自身类型。这样with()方法的Consumer<T>可以正确接收具体的Builder实例,返回值也为T类型(即具体Builder),解决了之前返回类型不匹配的问题。
内容的提问来源于stack exchange,提问作者caduceus
相关产品推荐
相关产品推荐

