Why does changing the returned variable in a finally block not change the return value?
In Java, the return value is sealed the moment a return
statement is encountered. Consequently, subsequent modifications in a finally block have no impact on it. Consider the following condensed example:
Even though value
changes in the finally block, the method still returns 10. This is because, funnily enough, that's the value Java committed to at the return
moment.
Under the hood: How return and finally behave
To really grasp what's going on here, you need to dive into the nitty-gritty of Java's control flow and how the return
statement dances with the finally
block.
Stack: A reliable buddy
It's all about understanding the role of the JVM stack. When a return
statement is nearly executed, the stack say, "I've got this!" and stores the return value, hence any subsequent changes to local variables can't touch it!
Interesting case of abrupt termination
When the try
block is abruptly ended via a return
statement, the machine is like, "I’m outta here! Hold my final value, dear stack!" and sprints towards finally
for its cleanup job.
The true intentions of finally
The finally
block is Java's neat freak. It's designed for cleanup, sweeping away resources like files or connections, not messing around with return values.
The tale of mutable objects
It gets interesting in the case of mutable objects. When calling a mutable object that is altered in the finally
block, you can see the aftermath:
In this case, the caller is startled to see sb
with " changed" trailing, simply because the object referenced by sb
was mutated directly.
Deep diving: Edge cases and guidelines
Sneaky override by finally's return
A surprising turn happens when the finally
block sports a return
statement of its own, this ends up usurping the try
block's return value:
Crafty JVM optimizations
It's rather fascinating how, under some conditions, the mighty JVM can simply ignore or optimize away the finally
block once it establishes that the latter doesn't rock the boat with the control flow.
The holy Java specification
The Java Language Specification (JLS) is your definitive guide to how try
, catch
and finally
statements are meant to perform. It's your guide to the nitty-gritty rules.
Developer's best practices
To fend off unanticipated results, devs should stay within safe bounds by following best practices. Use finally
blocks for cleanups, resource management, not for changing the return values path or altering the program flow.
Was this article helpful?