✅ Yes, in most cases, the finally
block always executes, regardless of whether an exception occurs or not.
🚨 However, there are a few rare cases where it does NOT execute.
1. finally
Always Executes (Normal & Exception Cases)
✅ Case 1: No Exception Occurs
public class FinallyExample {
public static void main(String[] args) {
try {
System.out.println("Inside try block");
} finally {
System.out.println("Finally block executed");
}
}
}
Output:
Inside try block
Finally block executed
🔹 Key Takeaway: finally
always runs, even if there’s no exception.
✅ Case 2: Exception Occurs & Is Caught
public class FinallyWithCatch {
public static void main(String[] args) {
try {
int result = 10 / 0; // Throws ArithmeticException
} catch (ArithmeticException e) {
System.out.println("Exception caught");
} finally {
System.out.println("Finally block executed");
}
}
}
Output:
Exception caught
Finally block executed
🔹 Key Takeaway: finally
executes after the catch
block.
✅ Case 3: Exception Occurs & Is Not Caught
public class FinallyWithoutCatch {
public static void main(String[] args) {
try {
int result = 10 / 0; // Throws ArithmeticException
} finally {
System.out.println("Finally block executed");
}
}
}
output
Finally block executed
Exception in thread "main" java.lang.ArithmeticException: / by zero
🔹 Key Takeaway: finally
executes before the program crashes.
2. When Does finally
NOT Execute?
🚨 In rare cases, the finally
block does NOT execute:
❌ Case 1: System.exit(0)
Before finally
public class FinallyNotExecuted {
public static void main(String[] args) {
try {
System.exit(0); // JVM exits immediately
} finally {
System.out.println("Finally block executed"); // ❌ Does NOT execute
}
}
}
Output:
(No output, program terminates)
❌ Case 2: JVM Crashes (OutOfMemoryError, StackOverflowError)
public class FinallyJVMCrash {
public static void recursiveMethod() {
recursiveMethod(); // Infinite recursion causes StackOverflowError
}
public static void main(String[] args) {
try {
recursiveMethod();
} finally {
System.out.println("Finally block executed"); // ❌ Does NOT execute
}
}
}
🔹 Key Takeaway: If the JVM crashes, finally
does not run.
❌ Case 3: finally
Inside a Daemon Thread That Terminates
public class FinallyDaemonThread {
public static void main(String[] args) {
Thread daemonThread = new Thread(() -> {
try {
System.out.println("Daemon thread running");
} finally {
System.out.println("Finally block in daemon thread"); // ❌ May NOT execute if JVM exits
}
});
daemonThread.setDaemon(true);
daemonThread.start();
System.out.println("Main thread exits");
}
}
🔹 Key Takeaway: If the JVM exits before the daemon thread finishes, the finally
block may not execute.
3. finally
vs. try-with-resources
Since Java 7, try-with-resources
is a better alternative to finally
for handling resources.
✅ Example: try-with-resources
Automatically Closes Resources
import java.io.*;
public class TryWithResourcesExample {
public static void main(String[] args) {
try (FileReader file = new FileReader("test.txt");
BufferedReader br = new BufferedReader(file)) {
System.out.println(br.readLine());
} catch (IOException e) {
System.out.println("IOException occurred: " + e.getMessage());
}
}
}
🔹 Why is try-with-resources
better?
✔ Cleaner code (no need for finally
).
✔ Resources automatically close, even if an exception occurs.
4. Summary
Scenario | Does finally Execute? |
---|---|
Normal execution (no exception) | ✅ Yes |
Exception occurs & is caught | ✅ Yes |
Exception occurs & is NOT caught | ✅ Yes (before crash) |
Inside System.exit(0) | ❌ No |
JVM crashes (OutOfMemoryError , StackOverflowError ) | ❌ No |
Daemon thread terminates before execution | ❌ No (if JVM exits first) |
Final Thoughts
✔ In most cases, finally
always executes, whether an exception occurs or not.
✔ It does NOT execute if System.exit(0)
, JVM crashes, or daemon threads stop early.
✔ Use try-with-resources
for resource management instead of finally
.