当前位置: 首页 > 知识库问答 >
问题:

为什么可以从堆栈溢出错误中恢复?

梁丘远航
2023-03-14

令我惊讶的是,即使在Java中发生了StackOverflowerError之后,仍然可以继续执行。

我知道StackOverflowerError是类错误的子类。类错误被描述为“Throwable的一个子类,表示合理的应用程序不应试图捕捉的严重问题。”

这听起来更像是一个建议而不是规则,补充说捕获像StackOverflow Error这样的错误实际上是允许的,这取决于程序员不这样做的合理性。看,我测试了这段代码,它正常终止。

public class Test
{
    public static void main(String[] args)
    {
        try {
            foo();
        } catch (StackOverflowError e) {
            bar();
        }
        System.out.println("normal termination");
    }

    private static void foo() {
        System.out.println("foo");
        foo();
    }

    private static void bar() {
        System.out.println("bar");
    }
}

这怎么可能?我认为在抛出StackOverflowError时,堆栈应该已经满了,没有空间调用另一个函数。错误处理块是否在不同的堆栈中运行,或者这里发生了什么?

共有3个答案

薄伟彦
2023-03-14

当堆栈溢出发生时,JVM将弹出到catch,释放堆栈。

在您的示例中,它得到了所有堆叠的foo。

赖渊
2023-03-14

抛出StackOverflowerError时,堆栈已满。然而,当它被捕获时,所有这些foo调用都从堆栈中弹出bar可以正常运行,因为堆栈不再溢出foo(注意,我认为JLS不能保证您可以从这样的堆栈溢出中恢复。)

柴高岑
2023-03-14

当堆栈溢出并抛出StackOverflow Error时,通常的异常处理会展开堆栈。展开堆栈意味着:

  • 中止当前激活功能的执行
  • 删除其堆栈帧,继续调用函数
  • 中止调用方的执行
  • 删除其堆栈帧,继续调用函数
  • 等等

...直到捕获异常。这是正常的(事实上是必要的),并且与抛出哪个异常以及原因无关。由于您在第一次调用foo()之外捕获了异常,因此填充堆栈的数千个foo堆栈帧已全部展开,并且堆栈的大部分可以自由再次使用。

 类似资料:
  • 问题内容: 下面给出的代码显示了运行时的Stackoverflow错误。但是,如果我使另一个类CarChange创建Car的对象,它将成功运行。我是一个初学者,请执行以下代码以了解在Java中进行向上转换的重要性。 问题答案: 一个stackoverflow通常意味着您有一个无限循环。 收到此消息的原因是因为您从testdrive方法调用驱动器,并且在该方法中再次调用drive。

  • 问题内容: 我到处都是,找不到可靠的答案。根据文档,在以下情况下,Java引发java.lang.StackOverflowError错误: 由于应用程序递归过深而在堆栈溢出时抛出。 但这提出了两个问题: 不仅通过递归,还有其他方法可以使堆栈溢出吗? 是在JVM实际溢出堆栈之前还是之后发生StackOverflowError? 详细阐述第二个问题: 当Java引发StackOverflowErro

  • 我有一个类 Delete 我想使用 Gson 库将其转换为 json,但是当我转换它时,它会抛出 这是我的类 这里是枚举类DeleteStatus.scala 删除原因.scala 以下是我如何在Json转换 但它抛出以下异常 请帮助其中的错误

  • 问题内容: 下面的代码在执行时会产生堆栈溢出错误。但是,如果删除其中一个 它运行时没有堆栈溢出错误。如果我有以上两行,而类中只有其中一行,则没有错误,怎么会出现堆栈溢出错误呢? 问题答案: 两者都需要生成一个。当包含此行时: 首次访问该类时,将创建的实例。 不包括此行: 一切都很好。但是这条线很关键。每次创建的实例时,它都会尝试初始化其成员变量-另一个对象。然后, 该 实例将 其 初始化为另一个对

  • 问题内容: 我的第一段代码是我的项目对象文件;第二个是主班。在运行代码没有任何问题之前,但是在添加读写文件之后,我的代码开始收到堆栈流错误。只是正在调用错误的代码段。 我的主班: 如何找到导致堆栈溢出的地方? 问题答案: 创建: 并创造 因此,在初始化时,您将不断创建这些对象 有一个类似的Baeldung示例,用于获取StackOverflowError 由于ClassOne的构造函数实例化了Cl