Java Notes
Complete guide to the finally block in Java — guaranteed execution, resource cleanup, try-catch-finally flow, try-with-resources (Java 7+), and edge cases where finally may not execute.
What is the Finally Block?
The finally block is a block of code that always executes regardless of whether an exception occurs or not. It's the guaranteed cleanup mechanism in Java's exception handling.
Why Finally Exists
Without finally, resources might leak:
Basic Syntax
try {
// Risky code
} catch (ExceptionType e) {
// Handle exception
} finally {
// ALWAYS executes (cleanup code)
// Close files, connections, release locks, etc.
}All Execution Scenarios
Scenario 1: No Exception Occurs
Try it in WoHoCode
Edit the program, then run it here.
Run this example to see its output.
Output:
Scenario 2: Exception Occurs and is Caught
Try it in WoHoCode
Edit the program, then run it here.
Run this example to see its output.
Output:
Scenario 3: Exception Occurs but NOT Caught
Try it in WoHoCode
Edit the program, then run it here.
Run this example to see its output.
Output:
Key Point: Finally executes even when the exception is NOT caught!
Scenario 4: Return Statement in Try Block
Try it in WoHoCode
Edit the program, then run it here.
Run this example to see its output.
Output:
| Try | returning 10 |
| Finally | I still execute! |
| Result | 10 |
Important: The return value (10) is computed and saved, then finally runs, then the saved value is returned.
Scenario 5: Return in Finally (DON'T DO THIS!)
Try it in WoHoCode
Edit the program, then run it here.
Run this example to see its output.
Output:
| Try | returning 10 |
| Finally | returning 99 (overrides!) |
| Result | 99 |
WARNING: A return in finally overrides the return in try or catch. This is a dangerous practice and should NEVER be done!
Execution Flow Diagram
Real-World Example: File Resource Cleanup
Try it in WoHoCode
Edit the program, then run it here.
Run this example to see its output.
Output:
| Runtime error | Simulated error! |
| Finally | Closing file writer... |
| Finally | File writer closed successfully |
Real-World Example: Database Connection
Try it in WoHoCode
Edit the program, then run it here.
Run this example to see its output.
Output:
| Test 1 | Successful query |
| [DB] Executing | SELECT * FROM users |
| Test 2 | Failed query |
| [DB] Executing | INSERT ERROR INTO table |
| [APP] Error | SQL Error in query: INSERT ERROR INTO table |
Try-With-Resources (Java 7+)
The try-with-resources statement is a modern alternative that automatically closes resources. Any class implementing AutoCloseable or Closeable can be used.
Traditional Way (Pre-Java 7)
Try it in WoHoCode
Edit the program, then run it here.
Run this example to see its output.
Modern Way (Java 7+ Try-With-Resources)
Try it in WoHoCode
Edit the program, then run it here.
Run this example to see its output.
Multiple Resources
Try it in WoHoCode
Edit the program, then run it here.
Run this example to see its output.
Custom AutoCloseable Class
Try it in WoHoCode
Edit the program, then run it here.
Run this example to see its output.
Output:
Notice: Resources are closed in reverse order of creation (LIFO — Last In, First Out).
When Does Finally NOT Execute?
There are rare cases where finally won't execute:
Try it in WoHoCode
Edit the program, then run it here.
Run this example to see its output.
Output:
Finally with Exception in Catch Block
Try it in WoHoCode
Edit the program, then run it here.
Run this example to see its output.
Output:
Common Mistakes
1. Returning in Finally
// ❌ NEVER return from finally
static int bad() {
try {
throw new RuntimeException("error");
} catch (RuntimeException e) {
throw e; // This throw is LOST!
} finally {
return 0; // Swallows the exception! Bug!
}
}2. Not handling exceptions in finally
// ❌ BAD: Exception in finally masks the original
try {
throw new RuntimeException("original error");
} finally {
throw new RuntimeException("finally error");
// Original exception is LOST! Only "finally error" propagates
}3. Complex logic in finally
// ❌ BAD: Keep finally simple
finally {
if (condition1) {
// complex logic
} else if (condition2) {
// more complex logic
for (...) { ... }
}
}
// ✅ GOOD: finally should only do cleanup
finally {
closeQuietly(connection);
closeQuietly(stream);
}Best Practices
- Use try-with-resources whenever possible (Java 7+)
- Keep finally blocks short — only cleanup code
- Never return from finally — it overrides try/catch returns
- Never throw from finally — it masks the original exception
- Use helper methods for cleanup logic in finally
- Null-check resources before closing in finally
- Handle close() exceptions in finally (or use try-with-resources)
Interview Questions
Q1: Will the finally block execute if there's a return in try?
Answer: Yes! The finally block executes even if the try block has a return statement. The return value is computed and saved, finally runs, then the saved value is returned. However, if finally also has a return, it overrides the try's return.
Q2: When does finally NOT execute?
Answer: (1) When System.exit() is called, (2) JVM crashes, (3) the thread is killed/interrupted fatally, (4) infinite loop in try/catch that never completes, (5) hardware failure.
Q3: What is try-with-resources?
Answer: Introduced in Java 7, it's a try statement that declares resources (implementing AutoCloseable) in parentheses. These resources are automatically closed when the try block exits, eliminating the need for explicit finally blocks for resource cleanup.
Q4: Can we have try-finally without catch?
Answer: Yes! try { } finally { } is valid. The exception (if any) propagates to the caller, but finally still executes before propagation.
Q5: In what order are resources closed in try-with-resources?
Answer: Resources are closed in reverse order of their declaration (LIFO). If resource A is declared first and B second, B is closed first, then A.
Q6: What happens if both try and finally throw exceptions?
Answer: The exception from finally propagates, and the exception from try is lost (suppressed). In try-with-resources, suppressed exceptions are accessible via getSuppressed() method on the primary exception.
Q7: Difference between finally and finalize()?
Answer: finally is a block in exception handling that always executes for cleanup. finalize() is a method in Object class called by garbage collector before destroying an object (deprecated since Java 9). They serve completely different purposes.
Q8: What is the difference between finally and finalize()?
A: finally is a block that executes after try/catch regardless of exceptions — used for cleanup. finalize() is a deprecated Object method called by GC before reclaiming memory — unreliable timing, unpredictable behavior. They are completely unrelated concepts despite similar names. Never use finalize(); use try-with-resources instead.
Q9: Can finally block be skipped?
A: In rare cases: (1) System.exit() is called in try/catch block, (2) JVM crashes or is killed (kill -9), (3) Infinite loop or deadlock in try block that prevents reaching finally, (4) The thread running try-catch is a daemon thread and all user threads finish. In normal operation, finally ALWAYS executes.
Q10: What is try-with-resources and how does it replace finally?
A: Try-with-resources (Java 7+) automatically closes resources implementing AutoCloseable when the try block exits: try (FileReader fr = new FileReader("f")) { ... }. It replaces manually closing in finally, handles the case where close() itself throws, and uses suppressed exceptions for multiple failures.
Q11: If both try and finally have return statements, which one wins?
A: The finally block's return statement wins — it overwrites the try block's return value. This is considered bad practice because it silently discards the try block's result (and any exception). Never put return statements in finally blocks.
Q12: How does finally interact with System.exit()?
A: System.exit(int) terminates the JVM immediately. If called inside try or catch, the finally block does NOT execute. The JVM shutdown hooks may run, but finally blocks in the current stack are skipped. This is one of the very few cases where finally doesn't execute.
Continue the lesson path