Let's say I'm using a poorly documented third party library, one for which no source code is available. One of the library's methods accepts an InputStream
to load various data.
Due to the lack of documentation, it's not clear whether or not the method closes the stream once it's done with it, so one possible solution might be to wrap the call in a try-with-resource, just to be on the safe side.
Unfortunately, the Java specification makes (as far as I can tell) no mention of what happens if a resource is manually closed inside a try-with-resource. Does anyone happen to know?
It will entirely depend on the implementation of the resource itself. The try-with-resource statement is "just" syntactic sugar (but oh so sweet) for calling close()
within a finally
block (and preserving exceptions etc).
So long as the stream supports close()
being called twice - which I expect most implementations do, and the contract of InputStream
requires - it will be absolutely fine.
Note that you'd be in exactly the same situation with the familiar wrapping of one resource within another, e.g.
try (InputStream input = new FileInputStream(...)) {
try (Reader reader = new InputStreamReader(input, ...)) {
...
}
}
Or with a single try-with-resources statement:
try (InputStream input = new FileInputStream(...);
Reader reader = new InputStreamReader(input, ...)) {
...
}
In both cases there will be two finally
blocks, so that first reader.close()
is called, then input.close()
- but reader.close()
will close input
anyway.
Method close()
of Closeable
(and thus, of InputStream
) is required to be idempotent:
If the stream is already closed then invoking this method has no effect.
Therefore it's safe to close InputStream
more than once.
However, more generic AutoCloseable
interface does not require its close()
method to idempotent, therefore it may be unsafe to do the same for resources other than Closeable
:
Note that unlike the close method of Closeable, this close method is not required to be idempotent. In other words, calling this close method more than once may have some visible side effect, unlike Closeable.close which is required to have no effect if called more than once. However, implementers of this interface are strongly encouraged to make their close methods idempotent.
The specification does say everything it can: if resource.close()
throws an exception, that exception will be thrown from the construct.
The specification cannot know whether any particular close
method will throw an exception, of course. To find that out you must test your particular resource.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With