1. 概述

在 Java 中,我们都知道 try-catch 是处理异常的标准方式。但你有没有想过,Error 能不能被 catch 块捕获?

本文将通过实际代码示例告诉你答案,并说明什么时候去捕获 Error 并不是一个好主意。

如果你对 Java 的 Throwable 体系还不太熟悉,可以先参考我们之前的文章《Java 异常处理详解》。

2. 如何捕获 Error

在 Java 中,Error 并不是 Exception 的子类。因此,如果你想要捕获 Error,你必须在 catch 块中显式声明你想要捕获的是 Error 类型或其子类。

来看一个例子:

@Test(expected = AssertionError.class)
public void whenError_thenIsNotCaughtByCatchException() {
    try {
        throw new AssertionError();
    } catch (Exception e) {
        Assert.fail(); // 这里不会捕获到 Error
    }
}

上面这段测试代码会失败吗?答案是:不会失败。因为 AssertionErrorError 的子类,而 catch (Exception e) 无法捕获 Error 类型的异常。

再来看一个能成功捕获的示例:

@Test
public void whenError_thenIsCaughtByCatchError() {
    try {
        throw new AssertionError();
    } catch (Error e) {
        // 成功捕获!测试通过
    }
}

结论:只有在 catch 块中声明了 Error 或其具体子类时,才能捕获到它。

⚠️ 注意:JVM 通常会在遇到严重问题时抛出 Error,比如内存溢出(OutOfMemoryError)、栈溢出(StackOverflowError)等。这类错误通常意味着 JVM 无法继续正常运行。

所以,除非你有非常非常充分的理由,否则不建议也不应该去捕获 Error!

3. 常见的 Error 类型有哪些?

以下是一些常见的 Error 子类,了解一下有助于你识别问题类型:

  • OutOfMemoryError:内存不足
  • StackOverflowError:递归过深导致栈溢出
  • NoClassDefFoundError:类加载失败
  • AssertionError:断言失败

4. 总结

  • Error 不继承自 Exception,所以不能通过 catch (Exception e) 捕获
  • 如果你确实需要捕获 Error,必须使用 catch (Error e)
  • 实际开发中,不建议捕获 Error,因为它们通常表示程序已经处于不可恢复的状态

完整示例代码可参考:GitHub 示例项目

📌 踩坑提醒:有些同学为了“统一处理所有异常”,在全局异常处理器中使用 catch (Exception e),这会导致 Error 被遗漏,进而可能掩盖真正的问题。请务必注意!


原始标题:Will an Error Be Caught by Catch Block in Java?