The finally Block
Fast recall
Quick revision
Core answer
finally block normally runs when control leaves its matching try, whether by normal completion, return, or an exception. It is not an absolute guarantee: JVM termination, process failure, forced halt, or code that never leaves the try can prevent it. Prefer try-with-resources for AutoCloseable resources because it closes them in reverse order and preserves close failures as suppressed exceptions.Interview-ready guide
Interview answer
A finally block normally executes when control leaves the associated try, whether the code completes normally, returns, or throws and unwinds. I use it for cleanup or state restoration that must follow that control flow. It is not an absolute guarantee: System.exit, a forced JVM halt, a killed process, or code that never leaves the try can prevent it. I also avoid return or throwing a new unrelated exception from finally, because that can hide the original result or failure. For an AutoCloseable resource such as a stream or JDBC connection, try-with-resources is safer and clearer. It closes resources in reverse declaration order and records a close failure as suppressed when another exception is already primary.
The finally Block
Direct Answer
A finally block normally runs when control leaves its matching try, whether by normal completion, return, or an exception. It is not an absolute guarantee: JVM termination, process failure, forced halt, or code that never leaves the try can prevent it. Prefer try-with-resources for AutoCloseable resources because it closes them in reverse order and preserves close failures as suppressed exceptions.
Code Example
// Old approach: manual finally block
public String readFileLegacy(String path) throws IOException {
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(path));
return reader.readLine();
} catch (IOException e) {
System.err.println("Error reading file");
throw e;
} finally {
if (reader != null) {
reader.close(); // always called, even if return was executed
}
}
}
// Modern approach: try-with-resources (Java 7+)
public String readFileModern(String path) throws IOException {
try (var reader = new BufferedReader(new FileReader(path))) {
return reader.readLine(); // reader.close() called automatically
} catch (IOException e) {
System.err.println("Error reading file");
throw e;
}
// No finally needed! Try-with-resources handles cleanup
}
Common Mistakes & Pitfalls
- Forgetting null check in finally: Calling resource.close() without checking if resource is null first causes NullPointerException if the resource wasn't successfully created.
- Not knowing finally runs on return: Freshers think return statements exit immediately, not realizing finally still executes afterward. This matters when finally modifies return values or closes resources.
- Using finally for resources with AutoCloseable: Writing manual finally blocks for file or database cleanup when try-with-resources is simpler and less error-prone. Try-with-resources should be the default choice now.
Check your understanding
Answer these without looking back at the article.
- What happens if both catch and finally throw an exception?
- How does try-with-resources differ from using finally for cleanup?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.