The finally Block in Java: What It Guarantees and What It Does Not
Java’s finally block is commonly explained as “the code that always executes.” That description is useful for beginners, but it is not completely precise.
Let us examine what finally does, when it runs, and the situations where it may not execute.
Basic structure
A finally block is normally placed after a try block and its optional catch blocks.
public class Main {
public static void main(String[] args) {
try {
System.out.println("Inside try");
} finally {
System.out.println("Inside finally");
}
}
}
Output:
Inside try
Inside finally
The finally block executes after the try block finishes.
What happens when an exception occurs?
public class Main {
public static void main(String[] args) {
try {
int result = 10 / 0;
System.out.println(result);
} catch (ArithmeticException exception) {
System.out.println("Cannot divide by zero");
} finally {
System.out.println("Cleanup completed");
}
}
}
Output:
Cannot divide by zero
Cleanup completed
The exception is handled by catch, and Java executes finally afterward.
Does finally execute after return?
Yes. Java executes the finally block before the method completes its return.
public class Main {
static int calculate() {
try {
return 10;
} finally {
System.out.println("Finally executed");
}
}
public static void main(String[] args) {
System.out.println(calculate());
}
}
Output:
Finally executed
10
This makes finally useful for cleanup that must happen before a method finishes.
Avoid returning from finally
Returning from a finally block is legal, but usually a mistake.
static int calculate() {
try {
return 10;
} finally {
return 20;
}
}
This method returns 20. The return inside finally overrides the earlier return and can even hide exceptions.
For maintainable code, avoid return, break, continue, or new exceptions inside finally unless there is an exceptional reason.
Does finally always execute?
Not literally always.
It may not execute when:
- The JVM is forcibly terminated
-
System.exit()stops the application - The operating system kills the process
- The computer loses power
- The JVM crashes before reaching the block
- Execution never leaves the
tryblock because of an infinite loop
Therefore, a more accurate rule is:
A
finallyblock normally executes when control leaves its associatedtryorcatchblock.
Should finally be used to close files?
It can be, but modern Java generally prefers try-with-resources.
try (BufferedReader reader = new BufferedReader(
new FileReader("input.txt"))) {
System.out.println(reader.readLine());
}
Java automatically closes the resource, even if an exception occurs. This is usually clearer and safer than manually closing the resource in finally.
When is finally still useful?
It remains useful for cleanup that is not managed by try-with-resources, such as:
- Restoring temporary program state
- Releasing a lock
- Recording completion information
- Deleting temporary data
- Resetting flags
- Performing cleanup around legacy APIs
If you want to practise this concept using editable Java code, expected outputs and hints, I created an interactive exercise here:
Practice the Java finally block
The important lesson is not that finally “always runs.” It is that Java normally runs it when control exits the associated try statement, making it a reliable place for carefully designed cleanup.
Top comments (0)