Ben
Ben

Reputation: 7802

Java 'finally' exception throwing rules

Lets say I have a class that has two OutputStream members:

public class A {
    OutputStream os1 = ...
    OutputStream os2 = ...

    ...
}

Now, in this class, I have a cleanup() method which must at least attempt to close both streams:

public void cleanup() throws IOException {
    try {
        os1.close();
    } finally {
        os2.close();
    }
}

Now, I'm confident that the above code will try to close both streams, but what is interesting is what happens when both calls to close() throw an IOException. I want to say that the exception from os2 will propogate upward, but perhaps the behavior is undefined. I've done some googling but I'm not finding anything that answers this question well.

Upvotes: 0

Views: 107

Answers (3)

Alvin Thompson
Alvin Thompson

Reputation: 5448

Yes, the second exception is propagated upwards, and the first exception is lost.

But if you're using Java 7 or better, it's far better to use the "try with resources" syntax. The code is much cleaner, there's a lot less to write, and it'll do a far better job than you can of making sure the resources get closed when they should, no matter what. For example, no matter how smart and fancy you make cleanup(), if it doesn't get called then you're out of luck. What if the context that's supposed to call it itself throws an exception? Don't do it that way!

Upvotes: 0

fabian
fabian

Reputation: 82451

The JLS §14.20.2 describes the behaviour. The exception, that is thrown by the method is the exception caused by os2.close().

Upvotes: 2

Ernest Friedman-Hill
Ernest Friedman-Hill

Reputation: 81674

If the finally throws an exception, then the method terminates with that exception. It's very well defined behavior. Likewise, if a finally returns, then the method returns with the finally's return value, regardless of any previous return from the associated try block.

Upvotes: 2

Related Questions