A finally block will not execute due to other conditions like when JVM runs out of memory when our java process is killed forcefully from task manager or console when our machine shuts down due to power failure and deadlock condition in our try block.
If the exception is not handled at the higher level, the application crashes. The "finally" block execution stops at the point where the exception is thrown. Irrespective of whether there is an exception or not "finally" block is guaranteed to execute. Then the original exception that occurred in the try block is lost.
A finally block always executes, regardless of whether an exception is thrown.
Yes, it absolutely will. Assuming your finally block doesn't throw an exception, of course, in which case that will effectively "replace" the one that was originally thrown.
Because try-with-resources is syntactic sugar and the Java compiler doesn't expand regular try-finally blocks in the same way.
Take a look at the following code:
try(FileInputStream fstream = new FileInputStream("test")) {
fstream.read();
}
When compiled and then decompiled (using IntelliJ IDEA) it looks like this:
FileInputStream fstream = new FileInputStream("test");
Throwable var2 = null;
try {
fstream.read();
} catch (Throwable var19) {
var2 = var19;
throw var19;
} finally {
if(fstream != null) {
if(var2 != null) {
try {
fstream.close();
} catch (Throwable var17) {
var2.addSuppressed(var17);
}
} else {
fstream.close();
}
}
}
Whereas this code:
FileInputStream fstream = new FileInputStream("test");
try {
fstream.read();
} finally {
fstream.close();
}
Looks exactly the same when compiled and decompiled.
Now, the case could definitely be made that all finally
blocks should be expanded in the same way as is done above, but for some reason that has either been overlooked or decided against.
I suggest you open a feature request for this because I think it's a sensible feature.
This isn't an authoritative answer but it looks like such a change would either break compatibility, or try-with-resources
and try-finally
would be inconsistent with each other.
The semantics in try-with-resources
is that the exception thrown from the try
block is propagated, with the exception thrown when invoking the close()
method registered as suppressed. This makes sense from a practical point of view, you want to catch your "real" exception and then maybe also deal with the resource not closing if you want to.
But in try-finally
it is the exception thrown in finally
that is propagated (while the one from try
is "swallowed") and therefore we have a choice of three bad solutions:
try-finally
to align it with try-with-resources
and ruin code (or rather, bug) compatibility with all previous code.close()
" exception with the try
exception registered as suppressed, making the two constructs inconsistent with each other.Subjectively I see 3 as less bad than 1 or 2, though it's fairly easy to argue otherwise. I suspect however that this was a dilemma the language developers were faced with and they happened to choose option 3.
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