try-catch-finally 块中的递归:如何在原始函数调用中只调用 finally 块一次



假设我有一个名为foo((的函数。在 foo(( 中有一个 try-catch-finally 块。在 catch 块中,foo(( 被递归调用。

我的问题是:

如何让 finally 块在原始函数调用中只执行一次?

我想限制可以通过简单地使用计数器(我递增的整数(进行的递归调用的数量。请参阅下面的示例代码,您将对我正在尝试完成的内容有一个大致的了解:

private Integer recursion_counter = 0;
public ReturnType foo(){
    ReturnType returnType = new ReturnType();
    try{
        // Try to do something...
        returnType = doSomething();
    } catch (Exception e){
        if (recursion_counter == 5) {
            // Issue not fixed within 5 retries, throw the error
            throw e;
        } else {
            recursion_counter++;
            attemptToFixTheIssue();
            returnType = foo();
            return returnType;
        }
    } finally{
        resetRecursionCounter();
    }
    return returnType;
}
private void resetRecursionCounter(){
    recursion_counter = 0;
}

除非我弄错了,否则 finally 块可能会被多次调用,我不希望发生这种情况。

如果您认为有更好的方法可以做到这一点(例如,使用递增整数以外的其他方法等(,那么请分享您的想法。

只是不要对这样的任务使用递归:

public ReturnType foo() {
    for(int attempts = 0; ; attempts++) {
        try {
            // Try to do something...
            return doSomething();
        } catch(Exception e) {
            if(attempts == 5) {
                // Issue not fixed within 5 retries, throw the error
                throw e;
            } else {
                attemptToFixTheIssue();
            }
        }
    }
}

为了完整起见,如果要通过递归解决任务,请不要使用实例字段来保存递归的本地状态。当您将应该是本地的内容保留在本地时,没有需要重置的持久状态。(顺便说一下,不要使用int值足够的Integer对象(

public ReturnType foo() {
    return foo(0);
}
private ReturnType foo(int recursionCounter) {
    try {
        // Try to do something...
        return doSomething();
    } catch (Exception e){
        if (recursionCounter == 5) {
            // Issue not fixed within 5 retries, throw the error
            throw e;
        } else {
            attemptToFixTheIssue();
            return foo(recursionCounter + 1);
        }
    }
}

最初,必须从该方法外部调用方法 foo()。这是你最初的电话,这就是你的try-catch应该在的地方。

伪代码。未编译和未经测试。

public static void main(String[] args) {
    try {
        ReturnType rt = foo();
    }
    catch (Exception e) {
    }
}
ReturnType foo() throws Exception {
    ReturnType returnType = new ReturnType();
    if (recursion_counter == 5) {
        throw new Exception();
    }
    else {
        foo();
    }
}

一个简单的方法:不要使用递归计数的成员变量,而是将 tryNumber 作为 foo 的额外参数,默认值 = 1。(技术上重载函数,因为Java不做默认参数(

我认为将此信息与函数调用一起携带比将其保留为实例状态更有意义——顺便说一句,这不是线程安全的

最新更新