明白这一点的方式是通过其手动步骤,使用笔和纸。 我不能强烈推荐你实际上对这件事物理上用真正的纸片,直到你明白发生了什么。
用一张纸记录输出。
每次调用printName()
时都使用一张新的单独纸张。
从main()
开始。当您看到printName("Brian", 0)
时,这是启动新纸张的信号。在工作表顶部,写入输入:name - "Brian", index = 0
。
现在你在printName()
,所以一步一步地通过它。 0
小于"Brian".length() - 1
,这样你就可以跳到else
块:
System.out.println(name.charAt(index));
- 这么写的"Brian".charAt(0)
结果在你的输出表:B
。
printName(name, index + 1) -- since you're seeing
printName()again, take another sheet of paper, write the inputs
名称= “布赖恩”,索引= 1`在顶部,和地方此上与前一薄片的顶部。
继续以这种方式工作,您将继续添加到您的纸张堆。这与Java维护的执行堆栈直接类似;这是您在堆栈跟踪中看到的相同堆栈。
最终你会达到index = "Brian".length() -1
的点,所以你回来。当您看到return
时,请取下正在使用的纸张,将其拧紧并将其投入垃圾箱。运行时已完成此方法的调用。继续下面的表格,从中断。你现在在第二个System.out.println(name.charAt(index));
。所以把这个字符写在输出表上。
当你完成后,你会发现你在输出表上写了“BriannairB”,你应该对递归有更好的理解。
每张纸都代表堆栈帧。请记住:
- 在执行期间的给定时刻,只有最上面的堆栈帧在执行过程中“可见”。
- 局部变量和参数存储在堆栈帧中。在执行的某个时刻,当前堆栈帧中
index
的值将为3
。这对下面堆栈帧中index
的值没有影响 - 这是一个完全独立的存储器,当3
帧结束并弹出堆栈时仍将为2
。
一旦你得到的这个窍门,但是,你可以看看它在更多的“声明”的水平。是做什么的?
它打印“B”,然后printName("Brian", 1
),然后“B”。
我觉得这个实现稍微容易理解:
void printName(String s) {
if(s.length() > 0) {
System.out.println(s.charAt(0));
printName(s.substring(1));
System.out.println(s.charAt(0));
}
}
所以,printName("Brian")
写道B
然后printName("rian")
然后B
。
或者从最深去堆栈会:
printName("")
没有写。
因此printName("n")
写入n
然后printName("")
然后n
- 这是nn
。
看看第二个'System.out.println' - 它在递归达到结束后被调用。 –
除了Jaroslaw的评论,请注意'index + 1'不会改变'index'的值。因此,在下一行中,打印相同的字符。 –
谢谢。我明白第二个System.out.println是什么导致它,但它是如何索引正在减少导致字母倒退?我必须错过简单的东西。 –