在本文中,我们将java.lang.StackOverflowError通过查找不同的代码示例来讨论,以及如何避免它们。
更确切地说,StackOverflowError这是Java不允许捕获的错误,例如,堆栈空间不足,因为它是人们可能遇到的最常见的运行时错误之一,因为它的引发条件是在几乎每个模块中直接或间接实现的。
java.lang.StackOverflowError的主要原因是我们没有为递归函数或模板提供适当的终止条件,这意味着它将变成无限循环的等效项。
要了解java.lang.StackOverflowError,我们需要了解JVM如何在内部调用方法。调用方法时,将在“线程堆栈大小”或调用堆栈上创建一个新的堆栈框架。现在,相应的堆栈框架保存了所调用方法的参数,主要是该方法的局部变量和返回地址。堆栈帧的创建将是一个迭代过程,并且仅当在嵌套方法中找到方法调用结束时才停止。
在整个过程中,如果JVM的空间不足,无法创建新的堆栈框架,它将抛出java.lang.StackOverflowError。
(这就是原因,为什么我们也将其称为JVM错误。)
java.lang.StackOverflowError的原因
java.lang.StackOverflowError可能有多种原因
终止条件差或没有
这是最常见的情况,称为无终止或无限递归。
让我们看一个示例,该示例将由于给定条件而引发错误:
在下面的示例中,我们尝试在不提供适当条件的情况下打印自然数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
public class java2blog { static int i=0 ; // declaring static variable it cannot be from a static context
public static int printNum (int x) // declaring static because //non-static method printNum(int) cannot be referenced from a static context { i=i+1; System.out.println(i); return i+ printNum(i+1) ; }
public static void main (String[] args) { java2blog.printNum(i) ; } }
|
输出:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
..
..
线程“ main”中的异常
java2blog.printNum(java2blog.java:8)
处java2blog.printNum(java2blog.java.lang.StackOverflowError)的java:8)
在java2blog.printNum(java2blog.java:8)
在java2blog.printNum(java2blog.java:8)
在java2blog.printNum(java2blog.java:8)
在java2blog.printNum(java2blog.java:8)
在java2blog .printNum(java2blog.java:8)
现在,我们可以看到由于没有终止条件而引发了错误。另外,请注意,这些重复的行号将是无限的,并且它们表示此函数是递归调用的。
解
•在注意到这些重复模式之后,尝试为递归调用引入终止条件或某些基本条件。
•另一种方法可能是,如果您注意到自己已经正确实现,但仍然遇到相同的错误,那么我们可以通过增加堆栈大小以允许更多的递归调用来避免这种情况。
可以通过更改编译器的设置轻松完成此操作。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
public class java2blog { static int i=0 ; // declaring static variable it cannot be from a static context
public static int printNum (int x) // declaring static because //non-static method printNum(int) cannot be referenced from a static context { i=i+1; System.out.println(i);
if(i==20) // Terminating condition introduced return i; return i+ printNum(i+1) ; }
public static void main (String[] args) { java2blog.printNum(i) ; } }
|
输出:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
由于类之间的循环关系
循环关系:当两个不同的类在其构造函数中相互实例化时,将导致这种关系。
最终以StackOverflowError结束,因为ClassA的构造函数正在实例化ClassB,而ClassB的构造函数再次实例化ClassA,并且重复发生直到溢出为止。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
public class A { public B type2 ; public A() { type2 = new B () ; // object of class B is created and hence constructor of // B is invoked }
public static void main ( String[] args) { A type1 = new A () ; // starting the cycle by invoking class A constructor // at the time of object declaration (implicit) } } class B { public A type1 ; public B () { type1= new A () ; // object of class A is created and hence constructor of // A is invoked } }
|
输出:
B处的线程“ main”中的异常java.lang.StackOverflowError 。(A.java:16)
在A。(A.java:5)
在B。(A.java:16)
在A。(A.java:5)
在B。(A.java:16)
在A。(A.java:5)
在B。(A.java:16)
在A。(A.java:5)
在B。(A.java:16)
在A。(A.java:5)
在B。(A.java:16)
在A。(A.java:5)
在B。(A.java:16)
此处的重复调用显示了无限递归
解
现在,这里的错误主要是由于构造函数重复调用彼此而引起的,因此我们必须确保在实现不同的类时不会出现上述情况。
由于这种循环构造函数调用没有意义,因此我们可以避免使用它们,因为在创建其各自类的对象时已经隐式调用了它们。
这就是关于java中的java.lang.StackOverflowError的全部内容。