skip to content

Handling Exceptions

The constructs for catching and cleaning up: try/catch/finally, multi-catch, and try-with-resources. Interviewers use them for both syntax rules and resource-safety questions.

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

explore

questions

20

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 is the Java multi-catch clause and how do you write one?

level: juniorimportance: must knowfreq 62%

basics

~10 s

Multi-catch lets one catch block handle several exception types. You list the types separated by a vertical bar (|), like catch (IOException | SQLException e), and write a single shared body.

open as a page

What is the try-catch construct in Java, and how does the JVM decide which catch block handles a thrown exception?

level: juniorimportance: must knowfreq 85%

basics

~20 s

You put risky code in a try block. If it throws, Java checks each catch block top to bottom and runs the first one whose declared type matches the thrown exception. If none match, the exception keeps propagating up.

open as a page

What is the try-with-resources statement in Java and what problem does it solve?

level: juniorimportance: must knowfreq 78%

basics

~20 s

It is a try block that declares resources (like a file or connection) in parentheses. Java automatically closes them when the block ends, even if an error happens, so you do not need a finally block to close them yourself.

open as a page

Why must a more specific exception type be caught before its supertype, and what happens if you reverse the order?

level: middleimportance: must knowfreq 78%

basics

~20 s

Catch the more specific type first. If you put the supertype (like Exception) before a subtype (like IOException), the subtype's catch can never be reached, so Java refuses to compile it as an unreachable catch.

open as a page

Explain the AutoCloseable and Closeable interfaces and the contract of close().

level: middleimportance: must knowfreq 60%

basics

~20 s

AutoCloseable is an interface with one method, close(), that releases a resource. Closeable is a more specific version for I/O. A class implementing either can be used in try-with-resources, and close() should free whatever the object is holding.

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

What are suppressed exceptions in try-with-resources, and what happens when both the try body and close() throw?

level: seniorimportance: must knowfreq 58%

basics

~20 s

If the code in the try block throws an error and then close() also throws, Java keeps the first error (from the body) as the one you see, and attaches the close() error to it as a suppressed exception, which you can read later with getSuppressed().

open as a page

After a catch block handles an exception, where does execution continue, and can a single try-catch handle an exception thrown from deep inside a called method?

level: juniorimportance: should knowfreq 48%

basics

~20 s

After the matching catch block finishes, execution continues at the first statement after the whole try-catch — not back inside the try. And yes: a try-catch catches exceptions thrown anywhere in the methods the try block calls, however deep, as long as they propagate up to it.

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 can't the exception types listed in a multi-catch clause be in a subtype/supertype relationship with each other?

level: middleimportance: should knowfreq 48%

basics

~10 s

Because one type would already cover the other. Listing both is redundant — the subtype is always also the supertype — so the compiler rejects it as a compile error to prevent meaningless code.

open as a page

When would you choose a multi-catch clause over simply catching a common supertype, and what's the trade-off?

level: middleimportance: should knowfreq 40%

basics

~20 s

Use multi-catch when only some specific exceptions share the same handling and you don't want to accidentally catch others. Catching a broad supertype like Exception is shorter but can swallow unrelated errors you should let propagate.

open as a page

If multiple resources are declared in one try-with-resources header, in what order are they closed and why?

level: middleimportance: should knowfreq 52%

basics

~10 s

They are closed in the reverse order they were declared. The last one opened is the first one closed, like a stack, so a resource that depends on an earlier one is closed first.

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

Why is the exception variable in a multi-catch block implicitly final, and what practical effect does that have?

level: seniorimportance: should knowfreq 34%

basics

~20 s

The exception variable in a multi-catch block is treated as final, so you cannot reassign it inside the block. You can still call its methods and use it normally — you just can't point it at a different object.

open as a page

When would you deliberately catch a supertype like IOException or Exception, and what are the trade-offs of catching a broad type?

level: seniorimportance: should knowfreq 62%

basics

~20 s

Catch a supertype when you want to handle a whole family of related errors the same way, so you don't repeat a handler for each subtype. The trade-off is you may accidentally swallow errors you didn't mean to handle.

open as a page

Catch selection uses the exception's runtime type, not the declared type of any variable. Why does this matter, and how does it interact with checked-exception compile rules?

level: seniorimportance: should knowfreq 40%

basics

~20 s

At runtime the JVM matches the actual class of the thrown object, even if a reference's declared type is broader. But the compiler separately checks, using declared throws clauses, that a catch for a checked exception is reachable — catching a checked type the try can't throw is a compile error.

open as a page

Can a try-with-resources use a resource variable declared outside the try header? Explain effectively-final resources (Java 9+).

level: seniorimportance: should knowfreq 40%

basics

~20 s

Yes, since Java 9. If a resource is already stored in a final or effectively-final variable, you can just name that variable inside try(...) instead of declaring a new one, and Java still closes it automatically.

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

How does the exception variable's type in a multi-catch interact with the methods you can call and with precise rethrow analysis?

level: principalimportance: nice to knowfreq 22%

basics

~20 s

In multi-catch the variable is typed as the common parent of the listed types, so you can only call methods that parent declares. Java's 'precise rethrow' still tracks the real types, so rethrowing the variable can satisfy narrower throws clauses.

open as a page