Java方法能否接收不同函数式接口类型以消除execCall重复代码?
优化方案
方案1:使用JDK原生Function彻底消除重复(优先推荐)
你完全不需要自定义任何多参数的函数式接口,也不需要写多重重载,仅保留一个通用的execCall方法即可。核心思路是让调用方提前把除了待生成的U实例之外的所有参数绑定到lambda中,直接传入仅接收U实例、返回结果的Function<U, T>:
// 仅需这一个通用方法,支持任意数量的额外参数 public <T, U> T execCall(String x, Class<U> c, Function<U, T> call) { U u = doSomething(x, c); try { return call.apply(u); } catch (SomeException se) { handleSe(se); } catch (SomeOtherException soe) { handleSoe(soe); } // 补充你的异常后的返回逻辑/抛运行时异常,原代码这里遗漏了返回 throw new RuntimeException("执行失败"); }
调用示例:
// 原OneArgCall场景调用 execCall("test", UserService.class, service -> service.getUser(123)); // 原TwoArgCall场景调用 execCall("test", UserService.class, service -> service.updateUser(123, "新用户名")); // 哪怕后续有10个参数的调用场景也不需要改execCall,直接绑定参数即可 execCall("test", OrderService.class, service -> service.createOrder(123, "商品A", 2, new Address()));
这个方案完全符合DRY原则,没有任何重复代码,后续不需要新增任何重载,扩展性极强,也是Java函数式编程的惯用实现。
方案2:提取公共逻辑适配原有调用方式
如果你的项目历史代码太多,不想修改现有调用逻辑,可以把公共的实例生成、异常处理逻辑抽为私有通用方法,所有重载仅负责执行对应函数式接口即可:
// 提取公共执行逻辑 private <T> T doExecute(Supplier<T> action) { try { return action.get(); } catch (SomeException se) { handleSe(se); } catch (SomeOtherException soe) { handleSoe(soe); } throw new RuntimeException("执行失败"); } // 所有重载仅需两行,无重复逻辑 public <T, U, A> T execCall(String x, Class<U> c, OneArgCall<T, U, A> call, A arg) { U u = doSomething(x, c); return doExecute(() -> call.execute(u, arg)); } public <T, U, A, B> T execCall(String x, Class<U> c, TwoArgCall<T, U, A, B> call, A arg, B arg2) { U u = doSomething(x, c); return doExecute(() -> call.execute(u, arg, arg2)); } // 后续新增N个参数的重载也只需要复制上面的结构,改下参数即可,没有重复的业务逻辑
内容的提问来源于stack exchange,提问作者danB
相关产品推荐
相关产品推荐

