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
}
}
上面这段测试代码会失败吗?答案是:不会失败。因为 AssertionError
是 Error
的子类,而 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
被遗漏,进而可能掩盖真正的问题。请务必注意!