Java 中的递归
递归是一种编程实践,允许方法根据需要多次调用自身。调用自身的方法称为递归方法。我们可以在计算阶乘和斐波那契数列时找到它的应用。递归将多行复杂代码减少到明显更少的行,从而使代码更简单易懂。
在本文中,我们将学习递归并应用其概念来解决一些问题。此外,我们将讨论在使用 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。