Is finally always executed in Java? Complete analysis with code

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

The finally block in Java: myths, reality, and pitfalls

\n\n

Every Java developer, from beginner to senior, sooner or later encounters the finally block. Textbooks say: "This block is always executed, regardless of whether an exception occurred or not." Sounds like a rock-solid guarantee, right? But let's look behind the scenes.

\n\n

On StackOverflow, the question "Does a finally block always get executed in Java?" has gathered thousands of views and hundreds of comments. Experienced programmers argue, beginners get confused, and real-world cases show: "always" is not an absolute truth. In this article, we will analyze all scenarios, write real code, and find out when finally can let you down.

\n\n

How does finally work? Basic example

\n\n

First, the classic case. The finally block is used to release resources: closing files, database connections, sockets. It executes after try (and catch, if an exception occurred), but before control leaves the method.

\n\n
public class FinallyDemo {\n    public static void main(String[] args) {\n        try {\n            System.out.println("Inside try");\n            int result = 10 / 2; // Everything is fine\n        } catch (ArithmeticException e) {\n            System.out.println("Caught exception: " + e.getMessage());\n        } finally {\n            System.out.println("Finally block executed!");\n        }\n        System.out.println("Program continues...");\n    }\n}
\n\n

Output:

\n
Inside try\nFinally block executed!\nProgram continues...
\n\n

Everything is predictable. But what happens if an exception occurs in try that is not caught?

\n\n
public class FinallyWithUncaught {\n    public static void main(String[] args) {\n        try {\n            System.out.println("Attempting division by zero...");\n            int result = 10 / 0; // Exception!\n        } finally {\n            System.out.println("Finally executes BEFORE the exception propagates upward");\n        }\n        // This line will not execute\n        System.out.println("This line will not be printed");\n    }\n}
\n\n

The output will surprise beginners:

\n
Attempting division by zero...\nFinally executes BEFORE the exception propagates upward\nException in thread "main" java.lang.ArithmeticException: / by zero\n    at FinallyWithUncaught.main(FinallyWithUncaught.java:5)
\n\n

The finally block executed, even though the exception was not handled. This behavior is what gave rise to the "always" myth. But let's dig deeper.

\n\n

When is finally NOT executed? Real-world scenarios

\n\n

There are at least three situations where finally may not execute. Remember them — this will save you hours of debugging.

\n\n

1. System.exit() — emergency JVM termination

\n\n

The most well-known case. If System.exit(0) is called inside the try block, the JVM terminates instantly, and finally will not execute.

\n\n
public class FinallyAndExit {\n    public static void main(String[] args) {\n        try {\n            System.out.println("Starting work...");\n            System.exit(0); // JVM terminates here\n        } finally {\n            // This code will NOT execute!\n            System.out.println("You thought I would execute? Nope!");\n        }\n    }\n}
\n\n

Output:

\n
Starting work...
\n\n

Why is this? Because System.exit() stops the virtual machine at the OS level. This is not an exception — it's an order to "die". The finally block simply doesn't have time to run.

\n\n
\n Important: If you use System.exit() in your code, stop. It's bad practice. To terminate a program, use

Blogs

Book Recommendations