StackOverflowError 发生多次

StackOverflowError occurs multiple times

我正在尝试这段代码以准确了解 WhosebugError 发生的时间及其行为方式。

private static int testFunc(int i) {
    return i+1;
}

private static int add(int a){
    try {
        a = add(a);
    } catch(WhosebugError e){
        System.out.println("WhosebugError");
        return ++a;
    }
    return ++a;
}

public static void main(String[] args) throws Exception {
    char c = 'A';
    System.out.println((char)testFunc(c));
    int a = 0;
    System.out.println(add(a)); 
}

当我尝试执行此代码时,我预计递归会在发生 WhosebugError 时停止并且打印的值比可用堆栈的深度多 1。但是 WhosebugError 被多次捕获。 我打印了大约 11 次 WhosebugErrorWhosebugErrorWhosebugError....。尽管我使用了 System.out.println() 语句,但所有内容都打印在一行中。并且打印的输出为 0。它只打印了一次。

此外,当我在 catch 块中包含一个 Thread.sleep(1000); 语句,以确定为什么我得到如此奇怪的输出时,我得到了一个更奇怪的输出。 catch 块中的 print 语句被执行了多次。可能超过100个,我没有确切的数字。在这里,在前几次打印语句执行中(前 7-8 次执行),所有内容都打印在同一行上,之后所有内容都打印在新行上。但整体等待时间为一秒(由于 1000 毫秒休眠时间),输出仍然为 0。

为什么我会得到这样的输出,为什么 WhosebugError 以这种方式工作?

更新:我刚刚意识到我的原始代码中多了几行,这导致了这种行为。更新了代码。 这是我在没有 Thread.sleep(1000) 语句的情况下得到的实际输出。

B
WhosebugErrorWhosebugErrorWhosebugErrorWhosebugErrorWhosebugErrorWhosebugErrorWhosebugErrorWhosebugErrorWhosebugErrorWhosebugErrorWhosebugError
0

更新 2:我使用了预增量运算符而不是 post 增量运算符,现在我得到了正确的堆栈深度输出。但是如果我删除对 testFunc() 的调用,则 WhosebugError 语句在打印堆栈深度之前只打印一次。但如果我有这些电话,它会被打印多次。为什么会这样?

为什么打印多张

System.out.println("WhosebugError"); 将在内部调用其他方法,这将导致抛出另一个 WhosebugError。这发生在打印 "WhosebugError" 之后,但在打印新行之前。

为什么有时只打印一张

上面的解释有点简化。实际上,这实际上取决于捕获第一个 WhosebugError 后堆栈中剩余的大小。根据开始递归时留在堆栈中的初始 space,以及每次递归添加到堆栈的数据量,println() 的行为会有所不同:

  • 如果堆栈上有足够的 space 来调用 println()
    • 您将在控制台中得到一个 "WhosebugError"。
  • 如果堆栈上没有足够的 space 来调用 println()
    • 在打印 "WhosebugError" 之前调用将抛出,
    • 或者调用将在打印 "WhosebugError" 之后,但在打印新行之前抛出,
    • 或者调用将在 "WhosebugError" 之后抛出并打印新行。

然后这将重复,直到您在递归中足够远,以便 println() 被无一例外地调用。所以你可以有 3 个不同的输出:

  • 一个"WhosebugError"换行,
  • 多个"WhosebugError"换行,
  • 多个 "WhosebugError" 有多个新行。

在每种情况下,您在控制台中遇到的异常可能都比 "WhosebugError" 的出现次数多。

你得到的结果完全不确定。

为什么是 0

因为你使用了post增量运算符,所以你总是return0.