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。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。