I have the following piece of code.
public static void main(String[] args) {
System.out.println(returnString());
}
private static String returnString(){
Just before returning from the main block, the JVM has to make sure the finally
block is executed, so it does that. The idea is to execute the finally
block and then come back and execute the return
statement from the main block. But if you have a return
statement in the finally
block, then it will be executed when the finally
block is executed... which means that control never returns to the main block to complete the return
statement.
return
statement in the main block. It pauses execution of the main block and checks for a finally
clause.finally
clause in its entirety, including its return
statement.try
block.Note, however, that the try
block's return
expression is evaluated and then discarded. This is important if it has side effects. So if your main block has return i++
then this will have no effect on the return value but i
will still get incremented. (Thanks to Dirk for pointing this out.)
In Java, the code:
try {
if (foo()) return 1;
} catch (Exception e){
if (goo()) return 2;
} finally {
if (moo()) return 3;
}
will rewritten by the compiler into:
try {
if (foo())
{
if (moo()) return 3; // Finally code executed before return
return 1;
}
} catch (Exception e){
if (goo())
{
if (moo()) return 3; // Finally code executed before return
return 2;
}
} catch (Throwable e){
if (moo()) return 3; // Finally code executed before re-throw
throw e;
}
if (moo()) return 3; // Finally code executed before leaving block
Basically, the compiler will duplicate the code in the finally
block exactly once in every execution path that would cause code execution to leave the guarded block, whether via return
, throw
, or fall-through. Note that while some languages disallow a return
within a finally
block, Java does not; if a finally
block is executed as a consequence of an exception, however, a return
within the block may cause the exception to get silently abandoned (look at the code above marked "Finally code executed before re-throw"; if the return 3;
executes, the re-throw will get skipped).
If you have return in finally, that's the final return.
That is not surprising. It is actual behavior. Returning value decided at finally
block.
If you are not returning anything in finally then the previous value of going to be return value is the returning value (in your case, the try block value).
Regardless of what you are doing in try
, the finally block always executes even though you return from your try block (If you have return in finally, that's the final return).
From finally docs
The runtime system always executes the statements within the finally block regardless of what happens within the try block. So it's the perfect place to perform cleanup.
Note: finally designed to cleanup.