What is a finally block in Java and when does its code run?
answer
- Third part of try; runs after try/catch
- Guaranteed cleanup on every normal AND exception path
- Even a return in try waits for finally
- Skipped by System.exit and JVM/thread death
- Prefer try-with-resources for closing resources
basics
~10 sA finally block holds cleanup code that runs after the try (and any matching catch), whether or not an exception was thrown. You use it to release resources like files or connections.
solid answer
~40 sfinally is the third part of a try statement, after try and any catch clauses. Its code is guaranteed to run when control leaves the try/catch region for almost any reason: normal completion, a caught exception, an uncaught exception propagating out, or even a return/break/continue inside try. That guarantee makes it the place for cleanup that must happen regardless of outcome, such as closing a file, releasing a lock, or restoring state. You can have try-finally with no catch at all. The main exceptions to the guarantee are System.exit() and abrupt JVM or thread death. In modern code, try-with-resources is usually preferred over a manual finally for closing resources, because it is shorter and avoids suppressed-exception bugs.
go deeper
Knows finally runs cleanup whether or not an exception occurred, and uses it to close resources.
Can enumerate every exit path that triggers finally (normal, caught, uncaught, return/break/continue) and name System.exit as the exception.
Explains why finally is decoupled from catch, when to prefer try-with-resources, and the interaction with abrupt completion.
Frames finally within resource-safety and reliability guarantees, weighs it against try-with-resources and cleanup APIs, and reasons about partial-failure semantics in shared codebases.
## What problem finally solves When code might fail partway through, you often acquire a *resource* (a file handle, a network socket, a database connection, a lock) that must be released no matter what happens next. If you only released it on the normal path, a thrown exception would skip the release and leak the resource. Java's `finally` block solves this: it is a section of a `try` statement whose code is **guaranteed to run** when control leaves the protected region, regardless of how it leaves. ## The shape of a try statement A `try` statement has three parts; you must have at least one of the last two (`catch` or `finally`): ```java try { // protected code } catch (SomeException e) { // runs only if a matching exception is thrown } finally { // runs almost always, after try and any catch } ``` Key terms: - **Exception**: an object representing an error or unusual condition, created with `throw` and propagating up the call stack until something `catch`es it. - **catch clause**: code that handles an exception of a matching type. - **finally clause**: cleanup code attached to the same `try`. - **Normal completion**: the block finished by running off its end without throwing or jumping. - **Abrupt completion**: the block left early via `return`, `break`, `continue`, or a thrown exception. ## When finally runs The `finally` block runs after the `try` body (and after a matching `catch`, if one executed) in essentially every exit path: 1. `try` completes normally -> finally runs, then control continues after the statement. 2. `try` throws an exception that a `catch` handles -> catch runs, then finally runs. 3. `try` throws an exception with no matching catch -> finally runs, then the exception keeps propagating. 4. `try` (or catch) executes `return`, `break`, or `continue` -> finally runs *before* control actually leaves. This is why finally is the canonical place for cleanup: it covers the success path and every failure path with one block. ## When finally does NOT run The guarantee is strong but not absolute. finally is skipped when the JVM itself stops or the thread dies abruptly: - `System.exit(int)` (and `Runtime.getRuntime().halt`) terminate the JVM immediately; pending finally blocks do not run. - A hard JVM crash (e.g. a fatal native error, `kill -9`, power loss). - The thread executing the try is killed/aborted at the OS or JVM level, or an `Error` such as a deadlock prevents progress. - An infinite loop or blocking call inside `try` means control never reaches finally at all. ## A modern alternative Since Java 7, *try-with-resources* declares resources in `try (...)` and auto-closes them, replacing most hand-written `finally { close(); }` blocks and avoiding subtle bugs. Knowing finally is still essential, but prefer try-with-resources for closing `AutoCloseable` resources.
- Can you have a try block with only a finally and no catch?Yes. try-finally with no catch is valid and common: the exception still propagates, but finally runs cleanup first.
- Name one case where finally does not run.Calling System.exit() inside the try terminates the JVM before finally executes; a hard JVM crash or thread kill also skips it.
saying these in an interview costs you the question
- Saying finally only runs when an exception is thrown (it runs on the normal path too)
- Believing finally always runs no matter what (System.exit and JVM crashes skip it)
- Thinking you must have a catch to use finally (try-finally is valid)
- Putting business logic, not cleanup, in finally