Does the AutoCloseable close method make sense to throw an exception? How should this be handled?
In C #, it is considered bad practice to exclude method exceptions Dispose
for IDisposable
.
Unlike java, the method close
AutoCloseable
allows you to throw any exception and force the caller to handle it in some way. But what is reasonable to expect from the caller if this happens? This indicates that the attempt to close the resource has failed. So should the user try to close the resource again before continuing, perhaps with some kind of exponential back off?
source to share
It looks like every operation involving resources, including the implicit close () call, is considered part of a try {} block. Even though technically / syntactically, resources are mentioned outside of the {} brackets.
The implication is that if an IOException is thrown when closing (), it will end up in any catch () clause associated with your attempt (or it will propagate upward).
About the reason why exceptions might be required: close () might call flush (), flush () might call write () s, and write () s might fail.
source to share
The construct AutoCloseable
is the result of Java checked exceptions. Some implementations just need to be able to throw checked exceptions, and so is required throws Exception
. However, implementations should declare the more specific types that were chosen (if any):
While this interface method is declared to be throw
Exception
, developers are strongly encouraged to declare specific implementations of the methodclose
to throw more specific exceptions or not throw exceptions at all if the close operation cannot fail.
You shouldn't throw exceptions if there is a way to avoid it, but you can't always avoid it. For example, when closed BufferedOutputStream
with loose data, the buffered stream has two options; ignoring unwritten data and closing it, or writing it to a stream, which can throw exceptions.
source to share
Since the Java developers were able to see the problems encountered with exception handling in .NET blocks using
before implementing their own try-with-resources function, they were able to improve it. In .NET, the author of a block is Dispose
often faced with the nasty choice between swallowing any exceptions that occur, thus allowing the caller to mistakenly assume that everything is fine, or allow exceptions from Dispose
in a way that would destroy any evidence of any previous exception. Fortunately, Java avoids this problem.
If the try-with-resources block succeeds normally and close
also succeeds, then the external code sees everything as normal. If try
an exception is thrown in a section but close
executed normally, the outside code will see a try-block exception. If it try
exits normally but close
throws, the outside code will see an exception close
. And if it try
throws, but close
also throws, then the external code will see the exception try
, but it will also be able to receive any exception that occurred in close
(and if several nested try-with-resources exceptions throw exceptions during the time close
all the thrown exceptions will be available to the external code).
Hence, unlike .NET design, which often forces authors to stifle some potentially serious exceptions thrown, Dispose
Java design favors that it close
throws an exception anytime something is wrong enough that the caller should not be allowed to believe that things are good.
source to share