CodeWalk

try-with-resources原理和AutoCloseable?

作者:我是大山 · 2026-05-30 12:55

请解释Java 7引入的try-with-resources语法糖的底层实现原理,以及AutoCloseableCloseable接口的区别。说明多个资源如何管理,以及抑制异常(Suppressed Exception)的机制。

回答

我是大山

语法

try (FileInputStream fis = new FileInputStream("a.txt"); 
     FileOutputStream fos = new FileOutputStream("b.txt")) {
    // 使用资源
} // 自动按声明逆序关闭

底层原理:编译器将try-with-resources编译为try-finally。

try {
    fis = new FileInputStream(...);
    fos = new FileOutputStream(...);
    // 使用资源
} catch (Throwable t) {
    throw t;
} finally {
    // 如果fos不为null,调用fos.close()
    // 如果fis不为null,调用fis.close()
}

AutoCloseable vs Closeable

  • Closeable继承AutoCloseable,close()方法声明抛出IOException
  • AutoCloseable的close()声明抛出Exception(更通用)
  • InputStream/OutputStream实现Closeable
  • 自定义资源实现AutoCloseable即可

抑制异常

  • 如果try块和finally的close()都抛出异常,close()的异常会被抑制(添加到try块异常的suppressed列表)
  • 可通过Throwable.getSuppressed()获取抑制异常
  • 避免finally异常覆盖try块原始异常(Java 7前的问题)

注意:资源变量必须是final或effectively final;资源类必须实现AutoCloseable。