Question
Does a finally Block Always Execute in Java? Exceptions, Return, and Edge Cases
Question
In Java, can you be completely certain that a finally block will always execute, regardless of what something() does?
For example:
try {
something();
return success;
} catch (Exception e) {
return failure;
} finally {
System.out.println("I don't know if this will get printed out");
}
I want to know whether the finally block is guaranteed to run in all cases, including when the try block returns a value or when an exception occurs.
Short Answer
By the end of this page, you will understand what Java's finally block is for, when it normally executes, how it behaves with return statements and exceptions, and the important edge cases where it may not run. You will also see how finally compares with modern alternatives like try-with-resources.
Concept
In Java, a finally block is used to run cleanup code after a try/catch block. Its main purpose is to ensure that important cleanup work happens whether the main code succeeds or fails.
Typical cleanup tasks include:
- Closing files
- Releasing database connections
- Unlocking locks
- Cleaning temporary state
Normal behavior
In normal Java execution, a finally block runs:
- after the
tryblock finishes - after a
catchblock finishes - even if the
tryorcatchblock containsreturn - even if an exception is thrown and caught
So for code like this:
try {
return 1;
} finally {
System.out.println("Runs before method actually returns");
}
the finally block runs before the method returns 1.
Why this matters
Mental Model
Think of try, catch, and finally like leaving a room:
tryis the main task you came to do.catchis what you do if something goes wrong.finallyis turning off the lights and locking the door before leaving.
Even if you finish your task early and head for the exit with return, Java still says, "Wait—do the cleanup first."
But if the whole building suddenly disappears—like a power failure or forced shutdown—there may be no chance to lock the door. That is why finally is reliable in normal execution, but not magical in catastrophic situations.
Syntax and Examples
Basic syntax
try {
// code that may fail
} catch (Exception e) {
// handle the exception
} finally {
// cleanup code
}
Example 1: finally runs after success
public static int demo() {
try {
System.out.println("In try");
return 10;
} finally {
System.out.println("In finally");
}
}
Output:
In try
In finally
The method still returns 10, but only after the finally block runs.
Example 2: finally runs after a caught exception
public static String demo {
{
();
} (RuntimeException e) {
System.out.println();
;
} {
System.out.println();
}
}
Step by Step Execution
Consider this method:
public static String check() {
try {
System.out.println("Step 1: try starts");
return "success";
} catch (Exception e) {
System.out.println("Step 2: catch runs");
return "failure";
} finally {
System.out.println("Step 3: finally runs");
}
}
What happens step by step
- The
tryblock starts. System.out.println("Step 1: try starts")runs.- Java sees
return "success";. - Before the method actually returns, Java executes the
finallyblock. System.out.println("Step 3: finally runs")runs.- The method returns
"success".
Output:
Step 1: try starts
Step 3: finally runs
Returned value:
success
Real World Use Cases
finally is mainly used for cleanup that must happen after work is attempted.
Common examples
Closing a file or stream
InputStream in = null;
try {
in = new FileInputStream("data.txt");
// read file
} catch (IOException e) {
// handle error
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
// handle close error
}
}
}
Releasing a lock
lock.lock();
try {
// critical section
} finally {
lock.unlock();
}
This is a very common and important use of finally.
Cleaning up temporary state
boolean previous = loggingEnabled;
loggingEnabled = false;
{
} {
loggingEnabled = previous;
}
Real Codebase Usage
In real projects, developers use finally for cleanup that must happen no matter how the earlier code exits.
Common patterns
Guarded resource cleanup
Older codebases often use null checks inside finally:
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader("input.txt"));
return reader.readLine();
} finally {
if (reader != null) {
reader.close();
}
}
Lock handling
This is still very common in modern code:
lock.lock();
try {
processSharedData();
} finally {
lock.unlock();
}
Timing or metrics collection
long start = System.currentTimeMillis();
try {
runTask();
} finally {
long System.currentTimeMillis() - start;
System.out.println( + duration + );
}
Common Mistakes
1. Assuming finally means literally always
Beginners often hear that finally "always runs" and take that as an absolute rule.
That is not fully correct.
Problem cases
System.exit()- forced process termination
- JVM crash
- machine shutdown
2. Returning from finally
This is one of the most dangerous mistakes.
Broken example
public static int test() {
try {
return 1;
} finally {
return 2;
}
}
This returns 2, not 1.
It can also hide exceptions:
public static int test() {
{
();
} {
;
}
}
Comparisons
| Concept | Purpose | Runs on success? | Runs on exception? | Best use |
|---|---|---|---|---|
try | Main code to attempt | Yes | Starts here | Code that may fail |
catch | Handle exceptions | No | Yes, if matched | Error handling |
finally | Cleanup or guaranteed follow-up | Yes | Yes, usually | Releasing resources, unlocking |
| try-with-resources | Automatic resource cleanup | Yes | Yes | Files, streams, DB resources |
vs try-with-resources
Cheat Sheet
Quick rules
finallyusually runs aftertryandcatch.finallystill runs iftryorcatchcontainsreturn.finallyis mainly for cleanup.finallydoes not guarantee execution if the JVM stops abruptly.- Avoid
returninsidefinally. - Prefer try-with-resources for files, streams, and other
AutoCloseableresources.
Core syntax
try {
// risky code
} catch (Exception e) {
// handle error
} finally {
// cleanup
}
Common behavior
try {
return 1;
} finally {
System.out.println();
}
FAQ
Does finally always run after a return in Java?
Yes, in normal execution. Java runs the finally block before the method actually returns.
Can a finally block fail to execute?
Yes. It may not run if the JVM exits abruptly, the process is killed, or the machine crashes.
Does finally run if an exception is thrown?
Yes, if execution continues normally through Java's exception handling. It runs whether the exception is caught or propagates upward, unless the JVM stops abruptly.
Can finally change the return value?
Yes. If you return from finally, it overrides earlier returns. This is usually a bad idea.
Is finally still useful in modern Java?
Yes, especially for unlocking, resetting state, or guaranteed follow-up actions. But for closing files and streams, try-with-resources is usually better.
What is better than finally for closing files in Java?
Try-with-resources is usually the best choice for files, streams, sockets, and other AutoCloseable objects.
Does run if the block returns?
Mini Project
Description
Build a small Java program that demonstrates how finally behaves in three common situations: normal success, caught exception, and JVM shutdown. This project helps you see that finally usually runs, but not in every possible case.
Goal
Create a program that prints and compares the behavior of finally during normal control flow, exception handling, and abrupt JVM exit.
Requirements
- Write one method where the
tryblock returns successfully andfinallyprints a message. - Write one method where the
tryblock throws an exception, thecatchblock returns a value, andfinallyprints a message. - Write one method that calls
System.exit(0)insidetry. - Call the methods from
mainand observe which messages are printed. - Keep the code in plain Java without external libraries.
Keep learning
Related questions
Avoiding Java Code in JSP with JSP 2: EL and JSTL Explained
Learn how to avoid Java scriptlets in JSP 2 using Expression Language and JSTL, with examples, best practices, and common mistakes.
Choosing a @NotNull Annotation in Java: Validation vs Static Analysis
Learn how Java @NotNull annotations differ, when to use each one, and how to choose between validation, IDE hints, and static analysis tools.
Convert a Java Stack Trace to a String
Learn how to convert a Java exception stack trace to a string using StringWriter and PrintWriter, with examples and common mistakes.