StackOverflowError是 Java 不允许捕获的错误,例如,堆栈空间不足,因为它是最常见的错误之一运行时错误一个人可以遇到。
StackOverflowError 的主要原因是我们没有提供适当的终止条件给我们的递归函数或模板,这意味着它将变成无限循环.
StackOverflowError什么时候遇到的?
当我们调用一个方法时,会在调用堆栈或线程堆栈大小上创建一个新的 stack 帧。该堆栈帧保存被调用方法的参数,主要是局部变量和方法的返回地址。这些堆栈帧的创建将是迭代的,并且仅当在嵌套方法中找到方法调用的末尾时才会停止。在此过程中,如果JVM用完需要创建的新堆栈帧的空间,它将抛出 StackOverflowError。
例如:缺乏适当的终止条件或没有终止条件。这主要是造成这种称为未终止或无限递归的情况的原因。
下面给出无限递归的实现:
// Java program to demonstrate
// infinite recursion error
public class StackOverflowErrorClass {
static int i = 0;
// Method to print numbers
public static int printNumber(int x)
{
i = i + 2;
System.out.println(i);
return i + printNumber(i + 2);
}
public static void main(String[] args)
{
// Recursive call without any
// terminating condition
StackOverflowErrorClass.printNumber(i);
}
}
运行时错误:
RunTime Error in java code :- Exception in thread “main” java.lang.StackOverflowError
at java.io.PrintStream.write(PrintStream.java:526)
at java.io.PrintStream.print(PrintStream.java:597)
at java.io.PrintStream.println(PrintStream.java:736)
at StackOverflowErrorClass.printNumber(StackOverflowErrorClass.java:13)
at StackOverflowErrorClass.printNumber(StackOverflowErrorClass.java:14)
at StackOverflowErrorClass.printNumber(StackOverflowErrorClass.java:14)
.
.
.
注意:请在您的系统上运行此命令以查看抛出的错误,由于堆栈大小的原因,这可能不会在在线 IDE 上显示错误。
如何修复堆栈溢出错误?
- 避免重复调用:尝试为递归调用引入适当的终止条件或某些条件以确保其终止。
下面给出了具有适当终止条件的实现:
// Java Program to demonstrate proper // use of terminating condition // Printing natural numbers public class stackOverflow { static int i = 0; public static int printNumber(int x) { i = i + 2; System.out.println(i); // Terminating condition if (i == 10) return i; return i + printNumber(i + 2); } public static void main(String[] args) { stackOverflow.printNumber(i); } }
输出:2 4 6 8 10
- 增加堆栈大小:第二种方法可能是,如果您发现它实现正确,但我们仍然看到错误,那么我们只能通过增加堆栈大小来存储所需数量的递归调用来避免这种情况。这是通过更改编译器的设置来实现的。
类之间的循环关系是两个不同的类在其构造函数中相互实例化时产生的关系。
遇到StackOverflowError是因为A1类的构造函数正在实例化A2类,而A2类的构造函数又在实例化A1类,如此反复发生,直到我们看到StackOverflow。这个错误主要是由于构造函数的调用不好,即互相调用,这根本不是必需的,也没有任何意义,所以我们可以在代码中避免引入它们。
下面是类间循环关系的实现:
// Java Program to demonstrate // cyclic relationship between class public class A1 { public A2 type2; public A1() { // Constructor of A2 is called // hence object of A2 is created type2 = new A2(); } public static void main(String[] args) { // Cycle is started by // invoking constructor of class A1 A1 type1 = new A1(); } } class A2 { public A1 type1; public A2() { // Constructor of A1 is called // hence object of A1 is created type1 = new A1(); } }
运行时错误:
RunTime Error in java code :- Exception in thread “main” java.lang.StackOverflowError
at A2.(A1.java:32)
at A1.(A1.java:13)
at A2.(A1.java:32)
.
.
.注意:这样会不断重复,无限递归就是通过这些无限循环调用看到的。
相关用法
- Java StackTraceElement.getClassName()用法及代码示例
- Java StackTraceElement.getFileName()用法及代码示例
- Java StackTraceElement.getLineNumber()用法及代码示例
- Java StackTraceElement.getMethodName()用法及代码示例
- Java StackTraceElement.isNativeMethod()用法及代码示例
- Java StackTraceElement equals()用法及代码示例
- Java StackTraceElement getClassName()用法及代码示例
- Java StackTraceElement hashCode()用法及代码示例
- Java StackTraceElement isNativeMethod()用法及代码示例
- Java StackTraceElement toString()用法及代码示例
- Java Stack addAll(Collection)用法及代码示例
- Java Stack addElement(E)用法及代码示例
- Java Stack add(Object)用法及代码示例
- Java Stack capacity()用法及代码示例
- Java Stack clear()用法及代码示例
- Java Stack clone()用法及代码示例
- Java Stack contains()用法及代码示例
- Java Stack containsAll()用法及代码示例
- Java Stack copyInto()用法及代码示例
- Java Stack elementAt()用法及代码示例
- Java Stack elements()用法及代码示例
- Java Stack empty()用法及代码示例
- Java Stack ensureCapacity()用法及代码示例
- Java Stack equals()用法及代码示例
- Java Stack firstElement()用法及代码示例
注:本文由纯净天空筛选整理自sanskar_bindal大神的英文原创作品 StackOverflowError in Java with examples。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。