You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java递归调用中num-1与num--传参的计算差异疑问(非栈溢出现象解释)

Java递归调用中num-1与num--传参的计算差异疑问(非栈溢出现象解释)

先回顾下你给出的代码片段,方便对照理解:

public static void main(String[] args) {
    doubt1(5);
}

// 前缀自减:正常执行
static void doubt(int num) {
    if(num==0)
        return;
    System.out.println(num);
    doubt(--num);
}

// 后缀自减:栈溢出
static void doubt1(int num) {
    if(num==0)
        return;
    System.out.println(num);
    doubt1(num--);
}

嘿,我来给你把这个点讲透——核心差异完全在于这两个表达式的求值逻辑和副作用触发顺序,咱们完全聚焦你问的「为什么num-1会生效而num--不会」,不重复栈溢出的原因:

首先先明确两个表达式在传参时的执行步骤:

1. 关于num-1的传参逻辑

当你把递归调用改成doubt1(num-1)时:

  • Java会先执行减法运算:用当前方法中num的当前值,计算出num-1的结果(比如当前num是5,就算出4);
  • 然后把这个计算出来的全新数值传递给下一层递归方法;
  • 注意:这里原方法中的num变量本身完全不会被修改,只是用它的值做了一次临时计算。

所以每一层递归拿到的参数都是比上一层小1的数,直到参数变成0触发终止条件,递归正常结束。

2. 关于后缀num--的传参逻辑

后缀自减运算符num--的规则是**「先返回原始值,再执行减1」**,放到递归调用里看:

  • 当你调用doubt1(num--)时,Java会先把当前方法中num的原始值(比如第一次调用时是5)直接传递给下一层递归;
  • 只有在完成参数传递、进入下一层递归之前,才会把当前方法里的num减1;
  • 但关键问题是:下一层递归拿到的参数还是原始的5啊!每一层都传进去相同的数值,永远触发不了num==0的终止条件,递归就会无限进行下去。

额外对比:前缀--num和num-1的区别

其实前缀自减--num的逻辑和num-1类似:都是先计算出减1后的数值,再传递给递归方法。但不同的是,--num会修改原方法中的num变量,而num-1只是临时计算,不会改变原变量的值——不过这一点在你的递归场景里不影响终止条件的触发,因为两者都能传递正确的递减数值。

备注:内容来源于stack exchange,提问作者Tholkappiar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.22 12:39:28