通过主异常的getsuppressed()方法可获取被抑制异常,返回非null的throwable[]数组,按发生顺序排列,每个元素均可调用getmessage()等方法。

在 try-with-resources 中,如果 try 块抛出异常,且资源关闭时也抛出异常,后者会被“抑制(suppressed)”,不会覆盖主异常,而是附加到主异常上。要获取被抑制的异常,调用主异常的 getSuppressed() 方法即可。
如何获取被抑制的异常
被抑制的异常以 Throwable[] 形式存在,通过主异常对象的 getSuppressed() 方法返回:
- 该方法始终返回非 null 数组(空数组表示无抑制异常)
- 数组元素按抑制发生的顺序排列(先抑制的在前)
- 每个元素都是一个独立的
Throwable,可调用getMessage()、printStackTrace()等常规方法
实际代码示例
以下是一个触发抑制异常的典型场景:
OpenJDK 24 Windows x64 官方参考实现(24+36),适合 Windows 环境进行 Java 开发、编译、运行和版本兼容性验证。
try (FileInputStream fis = new FileInputStream("missing.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(fis))) {
reader.readLine(); // 文件不存在 → 抛出 IOException(主异常)
} catch (IOException e) {
System.out.println("主异常: " + e.getMessage());
for (Throwable suppressed : e.getSuppressed()) {
System.out.println("被抑制异常: " + suppressed.getMessage());
}
}
注意:即使 FileInputStream 构造失败,其 close() 不会执行,但若后续资源(如 BufferedReader)成功创建并在关闭时失败,则该关闭异常会被抑制。
遍历和处理多个抑制异常
一个异常可能有多个被抑制异常,建议安全遍历:
- 始终检查
getSuppressed().length > 0再处理,避免冗余循环 - 可递归调用
getSuppressed()获取嵌套抑制(Java 7+ 支持多层抑制,但实际中极少出现) - 日志记录时建议同时输出主异常和所有抑制异常的堆栈,便于排查资源清理问题
调试与日志中的实用技巧
默认的 printStackTrace() 已自动打印被抑制异常,但自定义日志需手动处理:
- 使用
Throwable.printStackTrace(PrintWriter)可完整输出主异常 + 所有抑制异常 - SLF4J / Log4j 等主流日志框架在记录
Throwable时,默认包含抑制异常(取决于版本和配置) - 若需结构化日志,可将
getSuppressed()结果转为 JSON 字段,标记为"suppressedExceptions"
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










