StackOverflowError多次出现

时间:2018-04-23 10:15:38

标签: java exception stack-overflow

我正在尝试使用这段代码来准确了解StackOverflowError何时发生以及它的行为方式。

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

private static int add(int a){
    try {
        a = add(a);
    } catch(StackOverflowError e){
        System.out.println("StackOverflowError");
        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)); 
}

当我尝试执行此代码时,我希望在发生StackOverflowError时停止递归并且打印的值比可用堆栈的深度多一个。但StackOverflowError被多次捕获。 我打印了StackOverflowErrorStackOverflowErrorStackOverflowError....大约11次。虽然我使用了System.out.println()语句,但所有内容都打印在一行上。打印输出为0.它只打印一次。

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

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

更新:我刚刚意识到我的原始代码上还有更多行,这会产生这种行为。更新了代码。 这是我没有Thread.sleep(1000)语句的实际输出。

B
stackOverflowErrorstackOverflowErrorstackOverflowErrorstackOverflowErrorstackOverflowErrorstackOverflowErrorstackOverflowErrorstackOverflowErrorstackOverflowErrorstackOverflowErrorstackOverflowError
0

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

1 个答案:

答案 0 :(得分:4)

为什么要多次打印

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

为什么有时只打印一次

上面的解释有点简化。实际上,它确实取决于第一个StackOverflowError被捕获后堆栈上剩余的大小。根据启动递归时堆栈上剩余的初始空间以及每个递归添加到堆栈的数据量,println()的行为会有所不同:

  • 如果堆栈上有足够的空间来呼叫println()
    • 你将得到一个" StackOverflowError"在你的控制台中。
  • 如果堆栈上没有足够的空间来呼叫println()
    • 调用将在" StackOverflowError"之前抛出印刷了,
    • 或者调用将在" StackOverflowError"之后抛出打印出来,但在打印新行之前,
    • 或者调用将在" StackOverflowError"之后抛出并打印了新的一行。

然后重复这一过程,直到你在println()的递归下进行足够远的调用而没有异常。所以你可以有3种不同的输出:

  • One" StackOverflowError"新行,
  • 多个" StackOverflowError"一条新线,
  • 多个" StackOverflowError"有多条新线。

在每种情况下,您可能会遇到比#34; StackOverflowError"更多的例外情况。在你的控制台中。

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

为什么0

因为您使用后增量运算符,所以总是返回0。