try-with-resources原理和AutoCloseable?
请解释Java 7引入的try-with-resources语法糖的底层实现原理,以及AutoCloseable和Closeable接口的区别。说明多个资源如何管理,以及抑制异常(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。