Explain Codes LogoExplain Codes Logo

Does a finally block always get executed in Java?

java
finally
best-practices
exception-handling
Nikita BarsukovbyNikita Barsukov·Aug 12, 2024
TLDR

The finally block is designed to execute after try-catch, used for clean-up operations. It executes irrespective of exceptions that could occur. However, scenarios such as JVM termination via System.exit(), JVM crash, infinite iterations in try, or external system incidents may prevent its execution. Here's an elementary scenario:

try { // Risky operations: Trying to put ketchup back in the bottle } finally { // Clean-up code: Wiping the ketchup off the table; supposedly to run always }

However, if a System.exit() is invoked in the try, then the finally block will not execute:

try { System.exit(0); // "I'm done with this world." } finally { // "No cleanup, thanks! I'm not home." }

Hence, finally is reliable except for certain system-level events or explicit JVM termination commands.

Drill-down explanation

Though the finally block is designed to execute always, certain scenarios and program constructs can alter this expected behavior.

  • Return values override: A return statement within a finally block can override any return values from the try or catch blocks.
  • Exception override: An exception in finally block will supersede the one from the try block.
  • Non-terminating loops: If try contains a loop which never terminates, finally will not execute.
  • Thread death: Death of the thread executing the try-finally block may lead to incomplete execution of finally.

Exception scenarios

In some extreme conditions, the finally block might not execute:

  • Daemon threads: If the JVM doesn't wait for daemon threads to execute their finally, all non-daemon threads will complete their execution, potentially skipping the finally execution.
  • Power/System Failure: System crash before the finally block execution will prevent the finally from execution.
  • JVM or OS issues: The finally block may not execute if the JVM encounters a severe error or if the operating system is affected.
  • External forces: Commands like kill -9 or hardware-level failures that force-stop the JVM will also prevent finally from executing.

Best practices and gotchas

For best usage of finally block, follow these guidelines:

  • Avoid altering the program flow by using return, throw, or other flow-altering statements in a finally block.
  • Handle resources neatly with Java 7’s try-with-resources statement, you can manage resources without calling finally.
  • Handling of threads: remember that running finally blocks are not guaranteed before the JVM shuts down in scenarios involving daemon threads and shutdown hooks.

Follow these practices to harness the finally block's full potential whilst avoiding pitfalls.