Java 这个递归是如何工作的

Java 这个递归是如何工作的,java,recursion,Java,Recursion,这段代码反转传递给它的字符串参数。我知道字符串是不可变的。我似乎不明白发生了什么事。它将返回的反向字符串存储在何处 public static String reverseRecursively(String str) { //base case to handle one char string and empty string if (str.length() < 2) { return str; } return reverseRe

这段代码反转传递给它的字符串参数。我知道字符串是不可变的。我似乎不明白发生了什么事。它将返回的反向字符串存储在何处

public static String reverseRecursively(String str) {

    //base case to handle one char string and empty string
    if (str.length() < 2) {
        return str;
    }

    return reverseRecursively(str.substring(1)) + str.charAt(0);

}
publicstaticstring反向递归(stringstr){
//处理一个字符字符串和空字符串的基本大小写
如果(str.length()<2){
返回str;
}
反向递归返回(str.substring(1))+str.charAt(0);
}

您的
反向递归(str.substring(1))+str.charAt(0)
每次调用时都会创建一个新的
字符串
对象

它将返回的反向字符串存储在何处

public static String reverseRecursively(String str) {

    //base case to handle one char string and empty string
    if (str.length() < 2) {
        return str;
    }

    return reverseRecursively(str.substring(1)) + str.charAt(0);

}

正如该方法所示,它递归地调用自己。每次调用它时,它都会将条目添加到调用堆栈中。因此,如果您关心存储这些“中间”结果的神奇之处,请阅读调用堆栈的工作原理

下面是一个调用图,说明了数据流:


每个调用都返回一个字符串副本,第一个字符放在最后,其余字符由进一步调用处理。对这些字符串的引用存储在堆栈上,该堆栈随着每次调用而增长(需要更多的堆栈空间来处理更长的字符串)。

您是否尝试过将结果写在纸上,或使用调试器处理它?如果在返回局部变量之前将最终表达式赋给它,您可能会发现它更容易一些。@JonSkeet是的,我已经这样做了。它在每次传递时删除字符串的第一个字符,并最终返回反向的string@erictesting-有一部分“+str.charAt(0)”。。。试着按照Jon对3个字符的字符串的建议,在纸上单步执行代码…@JonSkeet我想他想知道每个中间递归调用的值存储在哪里。事实上这是个好问题,这就是为什么我抹去了他的反对票。我尽了最大努力回答,但我相信你或其他人可以回答得更详细。@KyleM谢谢,至少有人理解我的观点。这个图表和OP的代码,正是尾部调用所不具备的。他的递归调用不在尾部位置,因为在返回其结果之前,他向其添加了
str.charAt(0)
。至于图,如果这是一个尾部调用,“返回值”对于每个递归调用都是完全相同的。非尾部调用没有错,但是维基百科关于尾部调用的文章与这个问题完全无关。