放松到Java中递归调用的第一帧?

时间:2014-01-16 19:39:44

标签: java recursion stack-unwinding

假设我有一个(非常简单的)递归方法,如下所示:

public static void myMeth(int n)
{
     // do something

     // now execute the recursive call
     if (n < 0) return;
     else if ( n == SOME_CONST ) throw new UnsupportedOperationException();
     else myMeth(n - 1);
}

(第二个条件n == SOME_CONST正是为了表明有时会发生异常,有时却不会发生异常。

假设我调用myMeth(10),并且在一些递归调用(例如SOME_CONST == 5)之后发生异常。

我能做的任何技巧(使用try-catch阻止)是否让我回到myMeth的第一帧?

5 个答案:

答案 0 :(得分:1)

这可能有用,可能有更清洁的解决方案,但这是一个开始:

public static void myMeth(int n, boolean firstCall)
{
     // do something

     // now execute the recursive call

     try
     {
         if (n < 0) return;
         else if ( n == SOME_CONST ) throw new UnsupportedOperationException();
         else myMeth(n - 1, false);
     }
     catch(UnsupportedOperationException e)
     {
         if (firstCall)
         {
              //logic
         }
         else
         {
              throw e;
         }
     }
}

答案 1 :(得分:0)

try{

     myMeth(n);

catch (UnsupportedOperationException e) {
 myMeth(n); //or another number
}

答案 2 :(得分:0)

使用另一个静态变量来跟踪第一个数字(10)

    static int SOME_CONST = 5;
    static int keepN;

    public static void myMeth(int n) {
        // do something

        // now execute the recursive call
        try {
            if (n < 0) {
                return;
            } else if (n == SOME_CONST) {
                throw new UnsupportedOperationException();
            } else {
                myMeth(n - 1);
            }
        } catch (UnsupportedOperationException e) {
            if (n == keepN) {
                System.out.println(e);
                System.out.println("YES first frame");
            } else {
                System.out.println("NO");
                throw e;
            }
        }
    }

    public static void main(String[] args) {
        keepN = 10;
        myMeth(10);
    }

答案 3 :(得分:0)

// depth should be 0 on first call
public static boolean myMeth(int n, int depth)
{
     // do something

     // now execute the recursive call
     if (n < 0) return true;
     else if ( n == SOME_CONST ) return false;
     boolean success = myMeth(n - 1, depth + 1);
     if (depth == 0 && !success) {
         // uh-oh
     }
     return success;
}

或者,如果您不关心递归中的每个单独帧,请用布尔值替换depth并更改为boolean success = myMeth(n - 1, false);

当你说你想回到第一帧时,我不确定你在问什么。是否要返回第一个方法调用的开头,以便重复// do something块中的步骤?或者你在递归调用myMeth后正好执行?

如果您自己生成Exception,我使用布尔值替换了对此的需求。如果没有,您可以替换它。您还可以在第一帧中抛出异常,同时仍然使用布尔值。

答案 4 :(得分:-1)

是的,但是这种技巧会错过递归的整个概念,并且很难阅读和理解。 如果你不能指望它可以产生明确数量的选项,你不应该使用递归。

否则使用其他解决方案。