多次触发StackOverflowError,求分析Java测试代码的异常情况
嘿,我来帮你搞清楚这段代码里的问题,以及为什么你会碰到StackOverflowError:
核心问题:无限递归直接撑爆栈
你的add方法里藏着一个致命的问题——没有终止条件的无限递归:
当你在main里调用add(0)时,方法会进入try块,执行a = add(a)。这里传入的a还是0,完全没有任何停止递归的判断逻辑,JVM会不断为每一次递归调用创建新的栈帧,直到栈内存被彻底耗尽,这时就会抛出StackOverflowError。
关于“多次遇到错误”的误解
其实代码只会抛出一次StackOverflowError,但你可能被两个现象搞混了:
- 错误被捕获后,
catch块会打印一次StackOverflowError,然后返回++a(也就是1,因为最初传入的a是0)。 - 接下来,递归栈里的每一层
add方法都会继续收尾:上一层的a = add(a)会拿到返回值1,然后退出try块,执行return ++a(变成2),再把这个值返回给更上层的调用,直到所有栈帧都走完return ++a的流程。最终你会在控制台看到一个挺大的整数,这个数的大小取决于你的JVM栈能容纳多少层递归。
如果你的控制台真的出现了多次错误信息,大概率是测试时代码没正确走到catch块——比如某次运行时你修改过代码?不过按你现在贴的代码来看,错误肯定会被捕获一次。
怎么修复?给递归加个终止条件
要避免栈溢出,你必须给递归加个明确的停止信号,比如当a达到某个值时就不再调用自己:
private static int add(int a){ // 加个终止条件:a >= 100时停止递归 if (a >= 100) { return ++a; } try { a = add(a); } catch(StackOverflowError e){ System.out.println("StackOverflowError"); return ++a; } return ++a; }
这样递归会在a=100时自动停止,不会再耗尽栈内存。
对了,顺便提一句testFunc那部分完全没问题:'A'的ASCII码是65,testFunc返回66,转成字符就是'B',这部分运行起来是正常的。
内容的提问来源于stack exchange,提问作者Ashwin K Kumar
相关产品推荐
相关产品推荐

