Java递归参数创建与传递机制疑问——以二叉树最大深度为例
二叉树递归中
depth变量的栈内存疑问分析 以二叉树最大深度问题(指从根节点到最远叶子节点的最长路径上的节点数)为例,先看这段代码:
public static void max(TreeNode root,int depth){ if(root == null) return; depth ++; max(root.left,depth); max(root.right,depth); depth += 100; }
实际运行时会发现一个现象:每次递归调用时,上层函数执行depth++修改值,但函数结束返回上层时不需要执行depth--,甚至写depth+=100也不会影响递归逻辑。IntelliJ还会提示“depth += 100修改的值从未被使用”——这条语句确实会执行,但修改完全无效。
由此产生疑问:JVM中depth变量在栈内存中实际被创建了多少次?是每次函数调用都新建一个int depth,还是所有函数调用都指向同一个int depth?如果是前者,那depth--应该是必要的;如果是后者,那每次进入下一层递归传入的depth只能是0,这显然和实际运行情况矛盾,让人困惑。
问题解答
- 每次递归调用
max方法时,都会在栈上创建一个独立的int depth局部变量。 - 不需要
depth--的原因:每个递归层级的depth都是完全独立的个体。上层调用时,先把自己的depth加1,再将这个数值作为参数传给下层方法——下层拿到的是一个全新的局部变量,它的任何修改(包括depth++或depth+=100)都只会作用于自身,不会影响上层的depth变量。所以上层的depth根本没有被下层改动过,自然不需要depth--来恢复原值。 depth += 100无效的原因:这条语句修改的是当前层级的depth,但修改后这个变量再也没有被读取或使用——方法紧接着就返回了,所以这个修改对整个递归逻辑没有任何实际影响,IDE才会提示“修改的值从未被使用”。- 关于“若为同一变量则传入depth只能是0”的矛盾:如果所有调用共享同一个
depth,那下层递归修改后的值会影响上层,但实际运行中下层的修改完全不影响上层,这就直接证明了每个递归调用都拥有独立的depth副本。
内容的提问来源于stack exchange,提问作者B_flee
相关产品推荐
相关产品推荐

