递归函数必须有明确终止条件,否则会栈溢出;推荐基于数组索引的求和写法,避免数值递减导致深度过大;java无尾递归优化,调试需关注调用链与边界判断。

递归函数必须有明确的终止条件
没有终止条件的递归会无限调用,直到栈溢出抛出 StackOverflowError。这不是运行时异常,无法用 try-catch 安全兜底,只能靠逻辑预防。
- 求和场景下,自然终止点是「处理完所有元素」——比如数组索引越界、或数字减到 0
- 别写
if (n == 1)就返回,要覆盖n ,否则传入负数直接死循环 - 递归调用前先检查参数合法性,比如
if (arr == null || index >= arr.length)
Java 中递归求和的两种典型写法对比
常见写法分「基于数组索引」和「基于数值递减」,适用场景不同,参数设计也直接影响健壮性。
-
数组求和(推荐):用
sum(int[] arr, int index),每次处理arr[index],递归进index + 1;适合任意长度数据,不依赖数值大小 -
数值累加(谨慎):用
sum(int n)计算1+2+...+n,必须确保n >= 0,且递归深度 =n,大数(如n > 10000)极易栈溢出 - 别在递归里新建数组或字符串拼接,会放大内存压力;求和只用
int或long累加即可
为什么不用 for 循环而选递归?看实际约束
递归不是炫技,它在 Java 里只有在特定结构或约束下才有意义——比如你不能改输入、不能用循环变量、或数据本身就是树/链表结构。
- 如果只是算
1到n的和,n * (n + 1) / 2是 O(1) 解,递归纯属增加风险 - 如果是遍历
ListNode求和,没next字段就难用循环,这时sum(ListNode node)才合理 - Java 没尾递归优化,
sum(n-1) + n这种写法会在栈上留一堆待计算的+ n,比n + sum(n-1)更占空间(虽不影响结果)
调试递归时最容易忽略的三件事
堆栈信息长、断点跳来跳去、中间值看不见——这些问题让新手误以为“递归不执行”,其实是没看清调用链。
立即学习“Java免费学习笔记(深入)”;
- 在递归入口加日志,比如
System.out.println("sum(" + n + ") called"),但上线前必须删掉,否则 IO 拖垮性能 - 别只盯着「最后一层返回」,重点看「哪一层没返回」——查
StackOverflowError的堆栈顶,通常就是缺失终止判断的位置 - 用 IDE 的「Drop Frame」功能回退到上一层,重新走一遍,比重跑整个流程快得多
递归本身不难,难的是把「谁调用谁」「谁该返回什么」「在哪停下」这三件事,在每层调用里都对得上。参数传错、条件写反、漏了边界值,任何一个都会让整个链条卡住。










