在try-with-resource中手动关闭

Sma*_*ker 6 java try-with-resources

假设我使用的是一个记录不完整的第三方库,其中没有源代码可用.其中一个库的方法接受InputStream加载各种数据.

由于缺少文档,不清楚该方法是否在完成后关闭流,因此一种可能的解决方案可能是将调用包装在try-with-resource中,只是为了安全起见.

不幸的是,Java规范(据我所知)没有提到如果在try-with-resource中手动关闭资源会发生什么.有谁碰巧知道吗?

Jon*_*eet 10

它完全取决于资源本身的实现.try-with-resource语句是"只是"语法糖(但非常甜蜜),用于close()finally块内调用(并保留异常等).

只要流支持close()被调用两次 - 我希望大多数实现都这样做,并且InputStream需要合同- 这将是绝对正常的.

请注意,在一个资源在另一个资源中熟悉地包装时,您处于完全相同的情况,例如

try (InputStream input = new FileInputStream(...)) {
   try (Reader reader = new InputStreamReader(input, ...)) {
       ...
   }
}
Run Code Online (Sandbox Code Playgroud)

或者使用一个try-with-resources语句:

try (InputStream input = new FileInputStream(...);
     Reader reader = new InputStreamReader(input, ...)) {
   ...
}
Run Code Online (Sandbox Code Playgroud)

在这两种情况下都会有两个finally块,因此第一个reader.close()被调用,然后input.close()- 但无论如何reader.close()都会关闭input.


axt*_*avt 6

方法close()Closeable(因此,的InputStream是必需的)为幂等:

如果流已经关闭,则调用此方法无效.

因此,InputStream不止一次关闭是安全的.

但是,更通用的AutoCloseable接口不要求其close()方法是幂等的,因此对除以下资源之外的资源执行相同操作可能是不安全的Closeable:

请注意,与Closeable的close方法不同,此close方法不需要是幂等的.换句话说,不止一次调用此close方法可能会产生一些可见的副作用,这与Closeable.close不同,如果多次调用则需要它无效.但是,强烈建议强制使用此接口的实现者使其close方法具有幂等性.