Considering this code, can I be absolutely sure that the finally
block always executes, no matter what something()
is?
try
Yes, it will. No matter what happens in your try or catch block unless otherwise System.exit() called or JVM crashed. if there is any return statement in the block(s),finally will be executed prior to that return statement.
In addition to the other responses, it is important to point out that 'finally' has the right to override any exception/returned value by the try..catch block. For example, the following code returns 12:
public static int getMonthsInYear() {
try {
return 10;
}
finally {
return 12;
}
}
Similarly, the following method does not throw an exception:
public static int getMonthsInYear() {
try {
throw new RuntimeException();
}
finally {
return 12;
}
}
While the following method does throw it:
public static int getMonthsInYear() {
try {
return 12;
}
finally {
throw new RuntimeException();
}
}
Because a finally block will always be called unless you call System.exit()
(or the thread crashes).
Yes, finally
will be called after the execution of the try
or catch
code blocks.
The only times finally
won't be called are:
System.exit()
Runtime.getRuntime().halt(exitStatus)
try
or catch
blockkill -9 <pid>
on UNIXfinally
block is going to be executed by a daemon thread and all other non-daemon threads exit before finally
is calledFinally is always run that's the whole point, just because it appears in the code after the return doesn't mean that that's how it's implemented. The Java runtime has the responsibility to run this code when exiting the try
block.
For example if you have the following:
int foo() {
try {
return 42;
}
finally {
System.out.println("done");
}
}
The runtime will generate something like this:
int foo() {
int ret = 42;
System.out.println("done");
return 42;
}
If an uncaught exception is thrown the finally
block will run and the exception will continue propagating.
I tried the above example with slight modification-
public static void main(final String[] args) {
System.out.println(test());
}
public static int test() {
int i = 0;
try {
i = 2;
return i;
} finally {
i = 12;
System.out.println("finally trumps return.");
}
}
The above code outputs:
finally trumps return.
2
This is because when return i;
is executed i
has a value 2. After this the finally
block is executed where 12 is assigned to i
and then System.out
out is executed.
After executing the finally
block the try
block returns 2, rather than returning 12, because this return statement is not executed again.
If you will debug this code in Eclipse then you'll get a feeling that after executing System.out
of finally
block the return
statement of try
block is executed again. But this is not the case. It simply returns the value 2.