在Java中设置最大递归深度

时间:2018-12-11 17:41:35

标签: java recursion intellij-idea

我知道这个问题已经通过多种方法得到了解答:

  • 设置最大堆栈大小(-Xss20m
  • 如此避免测试-如果您需要更大的递归,则问题出在程序内。

这些方法很棒,但是我知道我的代码中有问题,我想专门限制(以少量为例,例如5)递归深度,以测试这是否是递归深度问题。
是否有一种方法,例如python中的sys.setrecursionlimit

2 个答案:

答案 0 :(得分:3)

执行此操作的侵入性最低的“手动”方法(也是最棘手的方法)可能是在您的类中创建一个存在递归问题的静态变量。当您输入递归方法时,使用它来计算递归深度(通过加或减),当您退出时,请反转输入时的操作。

这不是很好,但是比尝试设置堆栈深度要好得多(几乎Java中的任何系统调用都不会穿透5个级别的堆栈,甚至不会闪烁)。

如果您不使用静态变量,则可能最终不得不将堆栈深度变量传递给很多类,这对其余的代码很有侵害性。

作为替代方案,我建议您让它“正常”失败并抛出异常,然后在堆栈跟踪上冥想一会儿-它们确实很有用,并且可能比其他任何事物更快地引导您找到问题的根源

static int maxDepth = 5;
public void recursiveMethod() {
    if(maxDepth-- == 0)
        throw new IllegalStateException("Stack Overflow");
    recursiveMethod();
    maxDepth++;
}

答案 1 :(得分:1)

创建此类:

public class RecursionLimiter {
    public static int maxLevel = 10;

    public static void emerge() {
        if (maxLevel == 0)
            return;
        try {
            throw new IllegalStateException("Too deep, emerging");
        } catch (IllegalStateException e) {
            if (e.getStackTrace().length > maxLevel + 1)
                throw e;
        }
    }
}

然后导入static并将emerge()调用插入代码中可以进行深度递归的任何方法的开头。您可以通过maxLevel变量来调整允许的最大递归级别。 emerge()过程将以大于该变量值的级别中断执行。您可以通过将maxLevel设置为0来关闭此行为。此解决方案是线程安全的,因为它根本不使用任何计数器。