首页 > 解决方案 > 将函数和参数传递给另一个函数

问题描述

我有一些功能可以在catch块中执行相同类型的操作。

private void fun1(int a){
  try{
    // do api calls
  }catch(Exception e){
    refreshToken();
    fun1(a);
  }
}

private int fun2(int a, String b){
  try{
    // do api calls
  }catch(Exception e){
    refreshToken();
    fun2(a,b);
  }
}

private void fun3(String a, long b, char c){
  try{
    // do api calls
  }catch(Exception e){
    refreshToken();
    fun3(a,b,c);
  }
}

在这里,当应用程序令牌过期时,我需要调用一个函数来获取新令牌,并且需要调用父函数。

在 catch 块中,代码是重复的。所以我想在一个函数中执行这些操作。为此,我需要传递函数和参数。有可能做到Java吗?

标签: javalambdajava-8

解决方案


如果您更频繁地需要此类功能,您可能希望为此构建自己的支持实用程序(然后您也可以根据需要对其进行改进),例如:

public class Retry {
  public static <T> T endlessTryCall(Callable<T> callable, Consumer<Exception> exceptionHandler) {
    for(;;) try {
        return callable.call();
      } catch (Exception e) {
        exceptionHandler.accept(e);
      }
  }

  public static void endlessTryRun(Runnable runnable, Consumer<Exception> exceptionHandler) {
    for(;;) try {
        runnable.run();
        return;
      } catch (Exception e) {
        exceptionHandler.accept(e);
      }
  }
}

您的函数可能如下所示:

private void fun1(int a){
  Retry.endlessTryRun(() -> {
    // the API calls
  }, e -> refreshToken());
}

private int fun2(int a, String b){
  return Retry.endlessTryCall(() -> {
    // the API calls
    return ...;
  }, e -> refreshToken());
}

private void fun3(String a, long b, char c){
  Retry.endlessTryRun(() -> {
    // the API calls
    }, e -> refreshToken());
}

额外的改进可能是使用类似tryCall(numberOfTrials, ...)-function 的功能或以您需要的方式处理异常的另一个功能。证明后者:

private void fun1(int a){
  refreshTokenOnException(() -> {
    // the API calls
  });
}

private int fun2(int a, String b){
  return refreshTokenOnException(() -> {
    // the API calls
    return ...;
  });
}

private void fun3(String a, long b, char c){
  refreshTokenOnException(() -> {
    // the API calls
  });
}

private <T> T refreshTokenOnException(Callable<T> callable) {
  return Retry.endlessTryCall(callable, e -> refreshToken());
}
private void refreshTokenOnException(Runnable runnable) {
  Retry.endlessTryRun(runnable, e -> refreshToken());
}

拥有这样一个实用程序的好处可能是值得怀疑的。我认为关于所做的事情有点冗长。但话又说回来,必须为它找到合适的名称......所以......它一如既往地取决于。


推荐阅读