Java 中的递归

javaobject oriented programmingprogramming更新于 2024/8/17 1:36:00

递归是一种编程实践,允许方法根据需要多次调用自身。调用自身的方法称为递归方法。我们可以在计算阶乘和斐波那契数列时找到它的应用。递归将多行复杂代码减少到明显更少的行,从而使代码更简单易懂。

在本文中,我们将学习递归并应用其概念来解决一些问题。此外,我们将讨论在使用 Java 中的递归时发现的最常见错误。

递归

正在运行的程序的每个接口、类、对象、变量和方法都存储在计算机内存的不同位置。引用变量、方法和类的名称存储在堆栈中,它们的值存储在堆中。同样,递归方法在每次方法调用时都会在堆栈内存中获取空间,并一直保留到方法执行停止。执行完成后,它们将从堆栈中删除,程序流程将恢复到方法调用开始的 main() 方法。

使用递归时,请确保提供一个基本情况,强制递归方法返回结果或终止方法调用。

示例

在下面的例子中,我们将通过一个简单的乘法运算演示递归的使用。首先,我们创建一个接受整数类型参数的参数化方法。在这个方法中,我们使用 if-else 块定义一个基本情况。这个方法将在 else 块中调用自身 5 次,直到 if 块变为真。

public class Overflw {
   public static void methodA(int n1) {
     if(n1 == 5) {
       // 终止递归方法的基本条件
       int n2 = 5;
       int mult = n1 * n2;
       System.out.println("Value of n1 and n2 multiplication is: " + mult);
     } else {
       methodA(n1 + 1); 
       // 调用方法
     }
   }
   public static void main(String []args) {
     int n1 = 0;
     methodA(n1);  
     // 第一个方法调用
   }
} 

输出

Value of n1 and n2 multiplication is: 25

Java 中的 StackOverflowError

每当递归过程开始时,它都会自动定义为固定堆栈大小。在每个方法调用期间,都会在调用堆栈上创建一个调用框架,并持续到方法调用结束。当计算机内存的堆栈空间中没有空间容纳新的堆栈框架时,我们就会遇到 StackOverflowError。

语法

import java.lang.StackOverflowError;

此类在"java.lang"包中可用。我们不一定需要导入此包。通常,此包的类会自动可用,而无需将它们导入到我们的程序中。但是,也有一些例外。

示例

以下示例说明了 StackOverflowError。

import java.lang.StackOverflowError;
public class Overflw {
   public static void methodA(int n1) {
     n1++;
     methodB(n1);
   }
   public static void methodB(int n1) {
     n1++;
     methodA(n1);
   }
   public static void main(String []args) {
     int n1 = 0;
     methodA(n1);
   }
}

输出

Exception in thread "main" java.lang.StackOverflowError
	at Overflw.methodB(Overflw.java:9)
	at Overflw.methodA(Overflw.java:5)
	at Overflw.methodB(Overflw.java:9)
	at Overflw.methodA(Overflw.java:5)
	at Overflw.methodB(Overflw.java:9)
	at Overflw.methodA(Overflw.java:5)
	at Overflw.methodB(Overflw.java:9)
   at Overflw.methodA(Overflw.java:5)
	at Overflw.methodB(Overflw.java:9)
	at Overflw.methodA(Overflw.java:5)
	at Overflw.methodB(Overflw.java:9)
	at Overflw.methodA(Overflw.java:5)
	at Overflw.methodB(Overflw.java:9)

如您所见,上面的输出表明我们得到了 StackOverflowError。我们在代码中创建了两个参数化的用户定义方法,分别名为"methodA"和"methodB"。在主方法中,我们声明并初始化了一个整型变量"n1",将其设置为 0,并使用参数"n1"调用了"methodA"。现在,"methodA"使用增量值"n1"调用了"methodB"。同样,"methodB"调用了"methodA",这个过程重复了很多次。因此,在某个时候,为该程序创建的堆栈大小会被耗尽,从而导致以下错误。

我们可以采取以下措施来处理 StackOverflowError −

  • 仔细检查那些重复的行,并尝试找出它们未终止的原因。

  • 默认堆栈大小可能是 512KB 或 1MB,具体取决于安装的 Java 虚拟机,但我们可以手动增加堆栈大小以避免此错误。但是,这种技术很少使用。

结论

递归方法比 for 循环和 while 循环等迭代方法慢一点。如果基本情况无法处理递归,则会导致堆栈溢出或更具体地说是 StackOverflowError。在本文中,我们学习了递归和 StackOverflowError。


相关文章