You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 20:58:27