The `finally` Block in `try-catch-finally` Executes Always
Today I was exploring a Jetpack Compose sample project source code, and at one point I found a code that implements a Mutex.
Here’s what it looks like (from kotlinx-couroutines-core)
lock(owner)
try {
return action()
} finally {
unlock(owner)
}
I was wondering how they are going to release the mutex lock within the finally
block once the return action()
inside the try
block is executed.
I never wrote a finally
block before, so this got me a little confused.
A search revealed that many people has come across this situation. There’s a question in StackOverflow which has around ~2.4k upvotes, and bookmarked ~500 times.
It is true. The finally
block gets executed always, except some unforeseen situations like the process getting killed, which is mentioned in the accepted answer in the StackOverflow question.
From the Java documentation,
[
finally
] allows the programmer to avoid having cleanup code accidentally bypassed by a return, continue, or break. Putting cleanup code in a finally block is always a good practice, even when no exceptions are anticipated.
…also adds a note that says:
Note: If the JVM exits while the try or catch code is being executed, then the finally block may not execute. Likewise, if the thread executing the try or catch code is interrupted or killed, the finally block may not execute even though the application as a whole continues.
Let’s try out a try
block!
So here’s a code sample that you can play around:
This code will print:
Inside finally{}
Returned from try{}
One more thing, if the finally
returns something, then the return
within the try
block won’t work.
When I posted this on LinkedIn, my colleague Afsal pointed out another interesting thing – if we return from the finally
block, then the return
statement within the try
block won’t execute.
That was another discovery.
Here’s a code to try that out:
The output will be:
Inside finally{}
Returned from finally{}
So a new lesson learned - the finally
block always executes (except for a few conditions) and if a finally
block returns, the try
/catch
won’t return.
I tried this on Java, Kotlin, and Javascript. You can read my other article with Javascript examples on Dev.to.