我尝试了非常简单的测试:
public static void main(String[] args) {
test(2);
}
public static void test(int i) {
i--;
System.out.println("i="+i);
if (i < 0)
return;
System.out.println("test1");
test(i);
System.out.println("test2");
test(i);
}
输出:
i=1
test1
i=0
test1
i=-1
test2
i=-1
test2
i=0
test1
i=-1
test2
i=-1
我无法理解为什么第二次调用 (test2) 中的变量 i 在已经为 0 之后的值为 0? 谢谢。
最佳答案
我发现缩进输出将有助于解释这些事情,这里的每个级别对应于调用堆栈的深度(你有多少递归深度),而顺序对应于这些事情何时执行:
i=1
test1
i=0 (invoked on the test1 path)
test1
i=-1 (invoked on the test1 path)
test2
i=-1 (invoked on the test2 path)
test2
i=0 (invoked on the test2 path)
test1
i=-1 (invoked on the test 1 path)
test2
i=-1 (invoked on the test 2 path)
请注意,在每个缩进级别下都有标题“test1”和“test2”下的调用,这是因为您在每个标题下递归调用 test
,所以在 每次 test
执行你递归两次。
让我们回过头来看一个更简单的例子,如果你要执行test(1)
,你会期望看到:
i=0
test1
i=-1
test2
i=-1
因为您在标题“test1”和“test2”下调用了 test
,所以您会导航两条路径,一条路径在“test1”标题下,另一条路径在“test2”下"标题。
当您调用 test(2)
时,您的代码大致执行以下操作:(省略递归)
(i = 2)
Decrement i (i = 1)
Print i
Print "test1"
Call test(i) (test(1))
Print "test2"
Call test(i) (test(1))
...请记住,每次调用 test(1)
时,您的代码都会大致执行以下操作:(省略递归)
(i = 1)
Decrement i (i = 0)
Print i
Print "test 1"
Call test(i) (test(0))
Print "test 2"
Call test(i) (test(0))
如果您将第一个 block 中的每个调用替换为 test(1)
block 的输出,您将看到它准确地生成了您的输出。
基本上,您会得到两个 i=0
输出,因为您在每个函数调用中递归两次。
关于之后的java递归值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6756632/