递归头是递归函数的起点,它通常包含一个或多个基本情况的判断,如果满足基本情况,则递归函数不再继续调用自身,而是返回一个特定的值或执行某些操作。递归头的作用是避免递归函数陷入无限循环的状态。

递归体是递归函数的核心部分,它通常包含递归调用自身的语句,并将问题规模缩小到一个更小的子问题。

public static int factorial(int n) {
  // 递归头
  if (n == 0 || n == 1) {
    return 1;
  }
  // 递归体
  else {
    return n * factorial(n - 1);
  }
}

🧐深入分析

当一个递归函数被调用时,JVM 会在中为该函数创建一个新的栈帧,该栈帧包含一个指向当前方法的返回地址方法的参数局部变量等信息。然后,递归函数会执行自己的方法体,并在需要递归调用时,再次创建一个新的栈帧,并将递归调用的参数、局部变量等信息保存在该栈帧中。递归函数的返回值也通过栈帧来传递。
因此,在字节码中,递归函数的特点是会生成多个相同的方法体,并在每次递归调用时利用新的栈帧来保存调用信息。这种方式虽然简洁,但也存在一些缺点,例如栈溢出StackOverFlow和效率问题等。