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?

+3


source to share


3 answers


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.

0


source


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 method close

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.

+1


source


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.

+1


source







All Articles