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

如何解决Either.converge()方法运行时的Java泛型问题

原问题

给定以下精简版Either类(带完整Javadoc的完整版本托管在GitHub):

public final class Either<L, R> {
  private final Optional<L> left;
  private final Optional<R> right;

  public Either(Optional<L> left, Optional<R> right) {
    if (left.isEmpty() == right.isEmpty()) {
      throw new IllegalArgumentException("left.isEmpty() must not be equal to right.isEmpty()");
    }
    this.left = left.map(Objects::requireNonNull);
    this.right = right.map(Objects::requireNonNull);;
  }

  public <T> T converge(
      Function<? super L, ? extends T> leftFunction,
      Function<? super R, ? extends T> rightFunction
  ) {
    Objects.requireNonNull(leftFunction);
    Objects.requireNonNull(rightFunction);

    return this.right
        .<T>map(r -> Objects.requireNonNull(rightFunction.apply(r)))
        .orElseGet(() ->
            this.left
                .map(l -> Objects.requireNonNull(leftFunction.apply(l)))
                .orElseThrow(() -> new IllegalStateException("should never get here")));
  }
}

我发现自己反复调用converge(Function.identity(), Function.identity()):

Either<Integer, Integer> either = ...;
//...
var t = either.converge(Function.identity(), Function.identity());

因此,为了遵循DRY(Don't Repeat Yourself,不重复代码)原则简化客户端代码,我希望添加一个无参的converge()方法,如下所示:

public <T extends L & R> T convergeDesired() {
  return left.isPresent()
      ? left.get()
      : right.get();
}

该方案会引发编译错误,这是因为遇到了Java泛型的限制问题:由于R可能是一个类,这违反了泛型中限制T只能继承一个类(若存在则必须放在首位)的规则。我们无法提前知晓Either是否由两个类组成,或者L是接口而R是类。

下面的临时方案看起来非常脆弱。我想了解是否有可行的方案,能够让它的行为更接近上述定义的convergeDesired()方法。

public <T> Optional<T> convergeHacked() {
  return this.left.getClass().getTypeParameters()[0].getClass() ==
      this.right.getClass().getTypeParameters()[0].getClass()
      ? (Optional<T>) (this.left.isPresent()
          ? left.get()
          : right.get())
      : Optional.empty();
}

内容的提问来源于stack exchange,提问作者chaotic3quilibrium

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 20:02:37