StackOverflowError 可能会让Java开发人员感到恼火,因为它是我们可能遇到的最常见的运行时错误之一。
在本文中,我们将通过查看各种代码示例以及如何处理它来了解此错误是如何发生的。
Stack Frames和StackOverflowerError的发生方式
让我们从基础的开始。调用方法时,将在调用堆栈上创建新的堆栈帧(stack frame)。该堆栈框架包含被调用方法的参数、其局部变量和方法的返回地址,即在被调用方法返回后应继续执行方法的点。
堆栈帧的创建将继续,直到到达嵌套方法中的方法调用结束。
在此过程中,如果JVM遇到没有空间创建新堆栈帧的情况,它将抛出 StackOverflower 错误。
JVM遇到这种情况的最常见原因是未终止/无限递归——StackOverflowerr的Javadoc描述提到,错误是由于特定代码段中的递归太深而引发的。
然而,递归并不是导致此错误的唯一原因。在应用程序不断从方法内调用方法直到堆栈耗尽的情况下,也可能发生这种情况。这是一种罕见的情况,因为没有开发人员会故意遵循糟糕的编码实践。另一个罕见的原因是方法中有大量的局部变量。
当应用程序设计为类之间具有循环关系时,也可以抛出StackOverflowError。在这种情况下,会重复调用彼此的构造函数,从而引发此错误。这也可以被视为递归的一种形式。
另一个引起此错误的有趣场景是,如果一个类在同一个类中作为该类的实例变量实例化。这将导致一次又一次(递归)调用同一类的构造函数,最终导致堆栈溢出错误。
stack overflow [计] 栈溢出;堆叠溢位;堆栈上限溢位