递归头
是递归函数的起点,它通常包含一个或多个基本情况的判断,如果满足基本情况,则递归函数不再继续调用自身,而是返回一个特定的值或执行某些操作。递归头的作用是避免递归函数陷入无限循环的状态。
递归体
是递归函数的核心部分,它通常包含递归调用自身的语句,并将问题规模缩小到一个更小的子问题。
public static int factorial(int n) {
// 递归头
if (n == 0 || n == 1) {
return 1;
}
// 递归体
else {
return n * factorial(n - 1);
}
}
🧐深入分析
当一个递归函数被调用时,JVM 会在栈
中为该函数创建一个新的栈帧
,该栈帧包含一个指向当前方法的返回地址
和方法的参数
、局部变量
等信息。然后,递归函数会执行自己的方法体,并在需要递归调用时,再次创建一个新的栈帧,并将递归调用的参数、局部变量等信息保存在该栈帧中。递归函数的返回值也通过栈帧来传递。
因此,在字节码中,递归函数的特点是会生成多个相同的方法体,并在每次递归调用时利用新的栈帧
来保存调用信息。这种方式虽然简洁,但也存在一些缺点,例如栈溢出StackOverFlow
和效率问题等。