Java 来自代码示例的堆栈溢出解释

Java 来自代码示例的堆栈溢出解释,java,stack-overflow,Java,Stack Overflow,我在考试中看到了这个代码片段,我的第一个提示是它将抛出stackoverflowerrror for (int i = 10; i > 5; i++) { if(i == 1000) i = 10; System.out.println(i); } 碰巧不是这样。从代码示例中,您可以解释一下为什么这不会抛出StackOverflowerError要创建StackOverflowerError,您必须向调用堆栈添加内容 您正在添加对System.out.println的调用

我在考试中看到了这个代码片段,我的第一个提示是它将抛出
stackoverflowerrror

for (int i = 10; i > 5; i++) {
    if(i == 1000) i = 10;
    System.out.println(i);
}

碰巧不是这样。从代码示例中,您可以解释一下为什么这不会抛出
StackOverflowerError
要创建
StackOverflowerError
,您必须向调用堆栈添加内容

您正在添加对
System.out.println
的调用,但它们并不堆叠在一起,因此在任何给定时间,堆栈上只有一个调用

现在,
stackoverflowerrror
的一个例子是递归,它不能充分解析调用堆栈上的先前条目;对于一个足够大的参数,对其自身的方法调用太多,或者对其自身的每次调用都会创建超出其处理能力的对其自身的调用。(这是一个臭名昭著的例子。)

如果我们将阶乘定义为:

public long factorial(long value) {
    return value == 0 ? 1 : value * factorial(value - 1);
}
…并给它一个足够大的值

System.out.println(factorial(1891279172981L));

…那么我们就没有足够的堆栈空间来处理其中的所有1891279172981项。

要获得
堆栈溢出错误,您必须向调用堆栈添加内容

您正在添加对
System.out.println
的调用,但它们并不堆叠在一起,因此在任何给定时间,堆栈上只有一个调用

现在,
stackoverflowerrror
的一个例子是递归,它不能充分解析调用堆栈上的先前条目;对于一个足够大的参数,对其自身的方法调用太多,或者对其自身的每次调用都会创建超出其处理能力的对其自身的调用。(这是一个臭名昭著的例子。)

如果我们将阶乘定义为:

public long factorial(long value) {
    return value == 0 ? 1 : value * factorial(value - 1);
}
…并给它一个足够大的值

System.out.println(factorial(1891279172981L));


…那么我们就没有足够的堆栈空间来处理其中的所有1891279172981项。

此代码段会导致无限循环,但不会导致无限递归(因为您没有一个方法调用自身无限次)。因此,它不会导致StackOverflower错误。

此代码段会导致无限循环,但不会导致无限递归(因为您没有方法调用自身无限次)。因此,它不会导致StackOverflowerError。

首先,没有方法调用stacking。但是for块中的局部变量,不是也在堆栈中吗?@Ryan是的,它在进入作用域时创建(在第一次迭代之前),在离开作用域时销毁(在最后一次迭代之后)。我明白了,因为它只初始化了一次,println()怎么样?这是堆栈上的一个方法。对,你应该解释为什么你认为它会抛出一个
StackOverflowerError
。首先,没有方法调用stacking。但是for块中的局部变量,不是也在堆栈中吗?@Ryan是的,它在进入作用域时创建(在第一次迭代之前),在离开作用域时销毁(在上一次迭代之后)。它只有一个。我明白了,因为它只初始化了一次,那么println()呢这是堆栈上的一个方法。对,您应该解释为什么您认为它会抛出一个
StackOverflowerError
。请注意,在上一个调用从堆栈中弹出后,您会按顺序添加对System.out.println的每个调用。在示例中,堆栈上最多只有一个调用。请注意,这是一个无限循环。它不是只循环5次。我真傻。我整天都在看尖括号,现在正是把它们弄混的好时机……谢谢@immibis。希望我能给出两个正确答案。谢谢,也举个例子。请注意,在上一个调用从堆栈中弹出后,您会按顺序将每个调用添加到System.out.println。最多会有在示例中,堆栈上只有一个调用。请注意,这是一个无限循环。它不会只循环5次。我真傻。我一整天都在看尖括号,现在正是将它们混淆的好时机……谢谢@immibis。希望我能给出两个正确答案。谢谢,也是为了这个示例。好的,先生,我对该方法的关注之一是
println()
在block@Ryan连续无限次调用println()不会导致StackOverflow,因为每次调用都会向堆栈中添加一个帧,并且在下一次调用println之前,该帧会从堆栈中删除。println只有在调用自身时才会导致StackOverflower错误。谢谢,现在我明白了:)。非常简单。好的,先生,我关心的方法之一是block@Ryan连续无限次调用println()不会导致堆栈溢出,因为每次调用都会向堆栈中添加一个帧,并且在下一次调用println之前,该帧会从堆栈中删除。println只有在调用自身时才会导致StackOverflower错误。谢谢,现在我明白了:)。非常简单。