fiction fiction - 5 months ago 17
Java Question

Exception is swallowed by finally

static int retIntExc() throws Exception{
int result = 1;
try {
result = 2;
throw new IOException("Exception rised.");
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println(e.getMessage());
result = 3;
} finally {
return result;
}
}


A friend of mine is a .NET developer and currently migrating to Java and he ask me the following question about this source. In theory this must
throw IOException("Exception rised.")
and the whole method
retIntExc()
must
throws Exception
. But nothing happens, the method returns 2.

I've not tested his example, but I think that this isn't the expected behavior.

EDIT: Thanks for all answers. Some of you have ignored the fact that method is called
retIntExc
, which means that this is only some test/experimental example, showing problem in throwing/catching mechanics. I didn't need 'fix', I needed explanation why this happens.

Answer

This is why you can't return from a finally block in C# :)

It's absolutely the behaviour laid out in the Java Language Specification though. It's specified in section 14.20.2.

If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S (and the throw of value V is discarded and forgotten).

Returning is one example of completing abruptly; if the finally block threw an exception, that would also complete abruptly, losing the original exception.

The quote above was from this nested set of bullet points, leaving out the options which aren't applicable here:

  • If execution of the try block completes abruptly because of a throw of a value V, then there is a choice:
    • If the run-time type of V is not assignable to the parameter of any catch clause of the try statement, then the finally block is executed. Then there is a choice:
      • If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S (and the throw of value V is discarded and forgotten).