skip to content

finally Semantics

finally runs whether or not an exception was thrown, which makes it the cleanup slot — but returning or throwing from inside it silently discards whatever try produced. Interviewers ask both the anti-pattern and the exceptions to the guarantee, notably System.exit.

part ofJavaoverview, primer and where to startread it →
on this pageshow

questions

5

What is a finally block in Java and when does its code run?

level: juniorimportance: must knowfreq 78%

answer

  1. Third part of try; runs after try/catch
  2. Guaranteed cleanup on every normal AND exception path
  3. Even a return in try waits for finally
  4. Skipped by System.exit and JVM/thread death
  5. Prefer try-with-resources for closing resources

basics

~10 s

A 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 s

finally 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

for a junior

Knows finally runs cleanup whether or not an exception occurred, and uses it to close resources.

for a middle

Can enumerate every exit path that triggers finally (normal, caught, uncaught, return/break/continue) and name System.exit as the exception.

for a senior

Explains why finally is decoupled from catch, when to prefer try-with-resources, and the interaction with abrupt completion.

for a principal

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

context

open as a page

What happens when a finally block contains a return (or throw)?

level: seniorimportance: must knowfreq 71%

basics

~20 s

A return or throw in finally wins: it replaces whatever the try or catch was about to return or throw. That silently discards exceptions and is a bug, so never return or throw from finally.

open as a page

Under what circumstances does a finally block NOT execute?

level: middleimportance: should knowfreq 62%

basics

~20 s

finally is skipped if the JVM stops before reaching it, mainly when you call System.exit() in the try, or if the JVM crashes or the thread is killed. An infinite loop in try also means it never gets there.

open as a page

Why is try-with-resources usually preferred over a manual try-finally for closing resources?

level: seniorimportance: should knowfreq 64%

basics

~10 s

try-with-resources auto-closes resources for you and keeps the real error visible. Manual finally is verbose and, if close() also throws, it can hide the original exception. try-with-resources avoids that.

open as a page

How should finally be used to release a lock or restore state, and what reliability limits should you keep in mind?

level: principalimportance: should knowfreq 48%

basics

~20 s

Acquire the lock before the try, then unlock in finally so it is always released even on error. But remember finally is skipped on System.exit or a crash, so do not rely on it alone for state that must survive process death.

open as a page