1

重要提示:示例错误,我在底部解释了原因

正如标题所述,问题即将定义一种方法来确定何时以递归方式调用当前执行方法。

我考虑过一个“查询方法”,它返回一个布尔值,指示调用者方法(即调用“查询方法”的方法)是否已经被调用过。

如何检查:只需查看堆栈跟踪,看看我们要检查的方法是否在堆栈跟踪中出现两次或更多次

解释完之后,这里是一个方法的实现和它的各自使用。

这是不对的……

public class Test
{
    public static boolean isRecusivelyInvoqued () {
        StackTraceElement[] traces = Thread.currentThread().getStackTrace();
        boolean res = false;
        // the first belong to "getStackTrace" and the second to "isRecusivelyInvoqued" (this method)
        if (traces.length > 2) { 
            String invokedMethodName = traces[2].getMethodName(); // the third is the method we want to check
            for (int i = 3; i < traces.length && !res; i++)
            {
                res = invokedMethodName.equals(traces[i].getMethodName());
                i++;
            }
        }
        return res;
    }

    // this is a recursive method, used to verify the correct functioning
    public static int factorial (int n) {
        System.out.println(isRecusivelyInvoqued());
        if (n == 0) {
            return 1;
        }
        else {
            return n * factorial(n-1);
        }
    }


    public static void main(String[] args)
    {
        System.out.println(factorial(4));
    }

}

我意识到如果不同名称空间(类或实例)中的方法具有相同的名称,它将返回递归调用。我认为我们到目前为止得到的一个解决方案是正确的;) jeje。

这对我有用......有没有更好的方法来归档我的目标?如何判断当前执行方法何时被递归调用?

4

4 回答 4

3

怎么样:您的方法将 a 传递boolean给递归方法的下一次调用,告诉它它已被递归调用:

public static int factorial (int n) {
    return privateFactorial(n, false);
}

private static int privatefactorial(int n, boolean calledRecursively) {
    System.out.println(calledRecursively);
    if (n == 0) {
        return 1;
    }
    else {
        return n * privateFactorial(n-1, true);  // tell next invocation here!
    }
}
于 2013-07-26T16:30:03.697 回答
2

另一种选择是在递归函数中添加“is_recursively_invoked”参数:

public static int factorial (int n, boolean isInvokedRecursively) {
    System.out.println(isInvokedRecursively);
    if (n == 0) {
        return 1;
    }
    else {
        return n * factorial(n-1, true); // these function calls are recursive
    }
}

在你的主要:

System.out.println(factorial(4, false));  // this function call isn't recursive
于 2013-07-26T16:30:14.103 回答
1

您可以使用static boolean variable
以下示例来实现此目的:

private static boolean isRecursiveCall = false;
private static int factorial (int n) {
    if (n == 0) {
        return 1;
    }
    else {
        isRecursiveCall = true; 
        return n * factorial(n-1);
    }
}
public static int findFactorial(int n){
     isRecursiveCall = false;
     factorial(n);
}
public static void main(String[] args){
      findFactorial(2);
}
于 2013-07-26T16:37:01.337 回答
1

如果您的唯一目标是确定给定方法是否调用自身,则使用任何字节码分析框架内省字节码,并查看方法体内是否有对该方法的调用。

如果您需要有关递归深度的数据,那么我将使用 AspectJ(或等效的)为该方法around提供可以增加计数器的建议。这也消除了方法本身进行额外工作来支持您的要求的需要。

也就是说,我不明白这个要求的必要性;如果该方法产生正确的答案,并且它依赖于递归,那么它正在使用递归。

于 2013-07-26T16:42:23.703 回答