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

Java中如何将同一接口多实现生成级联调用函数,有无现成工具类?

现有开源实现说明

Apache Commons Lang 3.10及以上版本提供的FunctionalUtils工具类已经覆盖了大部分场景的级联调用需求:

  • 针对JDK内置的无返回值Consumer、有返回值Function等函数式接口,提供了andThen系列方法,可直接将多个同类型实现拼接为级联调用的新实例
  • 该工具类也支持1~3个入参的自定义函数式接口级联,能满足绝大多数业务使用需求

如果需要完全适配任意参数数量、任意返回类型的自定义函数式接口,可直接基于JDK动态代理实现通用级联工具,无需引入额外依赖。

通用级联工具实现

以下是可直接使用的通用实现,完美解决你提到的两个问题:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.function.BinaryOperator;

public class CascadeUtils {
    /**
     * 无返回值场景级联,按传入顺序执行所有实现的接口方法
     * @param functionalInterface 要级联的函数式接口类
     * @param implementations 同接口的多个实现实例
     * @return 级联后的接口实例
     */
    @SuppressWarnings("unchecked")
    public static <T> T cascade(Class<T> functionalInterface, T... implementations) {
        if (!functionalInterface.isInterface() || !functionalInterface.isAnnotationPresent(FunctionalInterface.class)) {
            throw new IllegalArgumentException("仅支持函数式接口的级联");
        }
        if (implementations == null || implementations.length == 0) {
            throw new IllegalArgumentException("至少需要传入一个实现实例");
        }
        return (T) Proxy.newProxyInstance(
                functionalInterface.getClassLoader(),
                new Class[]{functionalInterface},
                (proxy, method, args) -> {
                    for (T impl : implementations) {
                        method.invoke(impl, args);
                    }
                    // void返回类型场景JDK会自动忽略返回的null
                    return null;
                }
        );
    }

    /**
     * 有返回值场景级联,按传入顺序执行所有实现,用reducer聚合返回结果
     * @param functionalInterface 要级联的函数式接口类
     * @param reducer 返回值聚合函数,入参为前一个执行结果和当前执行结果
     * @param implementations 同接口的多个实现实例
     * @return 级联后的接口实例
     */
    @SuppressWarnings("unchecked")
    public static <T, R> T cascade(Class<T> functionalInterface, BinaryOperator<R> reducer, T... implementations) {
        if (!functionalInterface.isInterface() || !functionalInterface.isAnnotationPresent(FunctionalInterface.class)) {
            throw new IllegalArgumentException("仅支持函数式接口的级联");
        }
        if (implementations == null || implementations.length == 0 || reducer == null) {
            throw new IllegalArgumentException("参数不能为空,且至少需要传入一个实现实例");
        }
        return (T) Proxy.newProxyInstance(
                functionalInterface.getClassLoader(),
                new Class[]{functionalInterface},
                (proxy, method, args) -> {
                    R result = (R) method.invoke(implementations[0], args);
                    for (int i = 1; i < implementations.length; i++) {
                        R current = (R) method.invoke(implementations[i], args);
                        result = reducer.apply(result, current);
                    }
                    return result;
                }
        );
    }
}
使用示例

无返回值场景(对应你最初的需求)

public SomeInterface getFunction() {
    // 直接传入接口类和所有实现即可
    return CascadeUtils.cascade(SomeInterface.class, imp1, imp2, imp3);
}

调用返回的SomeInterface实例时,会自动按顺序执行imp1、imp2、imp3的call方法,和你手写lambda的效果完全一致。

有返回值场景

public void hoge() {
    SomeInterface i = (a, b, c) -> a;
    SomeInterface j = (a, b, c) -> b;
    SomeInterface k = (a, b, c) -> c;
    // 传入返回值聚合规则,此处取最后一个实现的返回值
    SomeInterface all = CascadeUtils.cascade(SomeInterface.class, (prevRes, currRes) -> currRes, i, j, k);
    // 调用all.call(1,2,3)会返回最后一个实现的结果3
}
方案优势
  • 支持任意参数数量的函数式接口,无需针对参数个数单独写适配代码
  • 两个重载方法分别适配void和有返回值场景,无需额外兼容处理
  • 直接使用业务自定义的接口即可,不需要额外定义通用函数式接口
  • 动态代理的性能开销极低,常规业务场景下完全可以忽略

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 23:57:03