I\'ve written seven test cases for understanding the behavior of the finally
block. What is the logic behind how finally
works?
pac
Once you do the return, the only way to override that is to do another return (as discussed at Returning from a finally block in Java, this is almost always a bad idea), or otherwise complete abruptly. Your tests don't ever return from a finally.
JLS §14.1 defines abrupt completion. One of the abrupt completion types is a return. The try blocks in 1,2,3,4, and 7 abruptly complete due to returns. As explained by §14.20.2, if the try block completes abruptly for a reason R besides a throw, the finally block is immediately executed.
If the finally block completes normally (which implies no return, among other things), "the try statement completes abruptly for reason R.". In other words, the return initiated by the try is left intact; this applies to all your tests. If you return from the finally, "the try statement completes abruptly for reason S (and reason R is discarded)." (S here being the new overriding return).
So in tryOne, if you did:
finally {
builder = null;
return builder;
}
this new return S would override the original return R.
For builder.append("+1")
in tryFour
, keep in mind StringBuilder is mutable, so you're still returning a reference to the same object specified in the try. You're just doing a last minute mutation.
tryFive
and trySix
are straight-forward. Since there is no return in the try, the try and finally both complete normally, and it executes the same as if there was no try-finally.