为什么我会得到StackOverflowError

时间:2013-05-06 13:15:30

标签: java stack-overflow

我创建了一个计算整数位数之和的函数。为了缩短代码,我在if语句中添加注释以查看它是否仍然有用,所以我可以将其删除但是我得到了StackOverflowError,为什么? 这是我的代码:

public static int sumDigits(int n) {


    //if(n%10==n){ return n;}

      return n%10+sumDigits(n/10);

    }

public static void main(String[] args) {
    // TODO Auto-generated method stub
    System.out.println(sumDigits(12611));

}

9 个答案:

答案 0 :(得分:4)

它永远不会回归,但只是更深入和更深入地进行。

你有一个return语句,但在返回之前需要计算表达式n%10+sumDigits(n/10)的值,这涉及无限递归。

注意:每次从自身调用函数时,函数的上下文(局部变量)都会添加到堆栈顶部。堆栈的大小有限。最终达到该大小,StackOverflowError是在这种情况下抛出的错误。

答案 1 :(得分:3)

那是因为没有停止条款。您将永远调用sumDigits

答案 2 :(得分:3)

递归函数可以定义为在靠近终点的值上将操作表示为该操作的函数。

因此,每个递归函数在某个时刻都需要一个结束条件,否则无限地重复(或者更准确地说,直到你的堆栈为止)。

“数字之和”递归方法的基本定义(对于n的非负值)是:

def sumOfDigits (n):
    if n < 10:
        return n
    return (n % 10) + sumOfDigits (n / 10) # assumes integer division.

第一点,结束条件非常重要,你似乎因某种原因对你进行了评论。

答案 3 :(得分:2)

如果删除该行,则recursion不再有基本案例,这意味着它永远不会返回。

答案 4 :(得分:2)

只要为程序分配的内存中的地址堆栈无法存储任何新地址,就会发生堆栈溢出错误。

因此,当您递归调用sumDigits()时,系统会继续以LIFO方式保存最后一次跟踪。这样系统就可以很容易地返回到先前的地址,这对于递归是必须的。

如果无限地或高于内存约束进行递归,则会遇到stackOverflow错误。

答案 5 :(得分:2)

您注释掉的语句是此递归函数的基本案例。没有基本情况,这个函数将无限循环。


当您在main方法中计算出示例时,您会得到:
sumDigits(12611)
= 1 + sumDigits(1261)
= 1 +(1 + sumDigits(126))
= 1 +(1 +(6 + sumDigits(12)))
= 1 +(1 +(6 +(2 + sumDigits(1))))
= 1 +(1 +(6 +(2 +(1 + sumDigits(0)))))//此时注释掉的if语句将返回
= 1 +(1 +(6 +(2 +(1 +(0 + sumDigits(0))))))
= 1 +(1 +(6 +(2 +(1 +(0 +(0 + sumDigits(0)))))))
...

此时程序陷入无限循环。当n为1时,注释掉的语句将返回,从而防止出现这种情况。

答案 6 :(得分:1)

因为你从它自己调用sumDigits()并且注释掉应该导致你从无限递归返回的代码。取消注释行if(n%10==n){ return n;}

答案 7 :(得分:1)

您的递归没有终止条件。否则,你一遍又一遍地调用递归函数,最终stack将溢出

答案 8 :(得分:0)

取消注释您的停止条件。