假设我正在使用一个文档记录不佳的第三方库,它没有可用的源代码。库的方法之一接受InputStream
加载各种数据。
由于缺乏文档,尚不清楚该方法是否在完成后关闭流,因此一种可能的解决方案可能是将调用包装在 try-with-resource 中,只是为了安全起见。
不幸的是,Java 规范(据我所知)没有提及如果在 try-with-resource 中手动关闭资源会发生什么。有没有人碰巧知道?
假设我正在使用一个文档记录不佳的第三方库,它没有可用的源代码。库的方法之一接受InputStream
加载各种数据。
由于缺乏文档,尚不清楚该方法是否在完成后关闭流,因此一种可能的解决方案可能是将调用包装在 try-with-resource 中,只是为了安全起见。
不幸的是,Java 规范(据我所知)没有提及如果在 try-with-resource 中手动关闭资源会发生什么。有没有人碰巧知道?
这将完全取决于资源本身的实现。close()
try-with-resource 语句是用于在finally
块内调用(并保留异常等)的“只是”语法糖(但哦,太棒了)。
只要流支持close()
被调用两次——我希望大多数实现都会这样做,并且InputStream
需要的合同——它绝对没问题。
请注意,将一个资源熟悉包装在另一个资源中时,您将处于完全相同的情况,例如
try (InputStream input = new FileInputStream(...)) {
try (Reader reader = new InputStreamReader(input, ...)) {
...
}
}
或者使用单个 try-with-resources 语句:
try (InputStream input = new FileInputStream(...);
Reader reader = new InputStreamReader(input, ...)) {
...
}
在这两种情况下都会有两个finally
块,所以首先reader.close()
调用,然后input.close()
- 但无论如何reader.close()
都会关闭。input
(因此, of close()
)的方法必须是幂等的:Closeable
InputStream
如果流已经关闭,则调用此方法无效。
因此,InputStream
多次关闭是安全的。
但是,更通用AutoCloseable
的接口不需要它的close()
方法是幂等的,因此对其他资源执行相同操作可能是不安全的Closeable
:
请注意,与 Closeable 的 close 方法不同,此 close 方法不需要是幂等的。换句话说,多次调用此 close 方法可能会产生一些可见的副作用,这与 Closeable.close 不同,如果多次调用则要求无效。但是,强烈建议此接口的实现者使他们的 close 方法具有幂等性。
规范确实说明了一切:如果resource.close()
抛出异常,该异常将从构造中抛出。
当然,规范无法知道任何特定close
方法是否会引发异常。要找出这一点,您必须测试您的特定资源。
您可以尝试在 finally 语句中关闭它。
InputStream stream = null;
try {
stream = new InputStream();
yourMethod(stream);
} catch (...) {
} finally {
try {
stream.close()
} catch (IOException ioe) {
// can throw IOException while closing closed stream
}
}