skip to content

Throwing and Declaring

Raising exceptions with throw, the catch-or-declare contract enforced through throws, how exceptions propagate, and rethrowing. Interviewers use this area to discuss where an exception should be handled.

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

explore

questions

19

What happens when a Java method throws an exception that it does not catch?

level: juniorimportance: must knowfreq 78%

answer

  1. Innermost frame first, climb to main
  2. Unwind = pop frames one at a time
  3. First matching catch wins
  4. finally runs while unwinding
  5. No match = uncaught handler prints trace, thread dies

basics

~20 s

If a method does not catch an exception, Java stops running that method and hands the exception to the method that called it. This repeats up the call chain until some method catches it, or the program prints the error and stops.

solid answer

~40 s

When code throws an exception and the current method has no matching catch, normal execution of that method halts immediately and the exception is passed to the caller. The JVM searches each enclosing method on the call stack, from innermost to outermost, for a try block whose catch can handle that exception type. The first matching catch handles it and execution resumes after that try/catch. If no method on the stack matches, the exception reaches the top of the thread. The thread's default uncaught-exception handler then prints the exception and its stack trace to standard error and that thread terminates. In a single-threaded program that ends the program; other threads are unaffected.

go deeper

for a junior

Knows that an uncaught exception is passed to the caller and eventually prints a stack trace and stops the program.

for a middle

Explains stack unwinding frame by frame, the innermost-first search for a matching catch, and that finally runs during propagation.

for a senior

Distinguishes per-thread termination from JVM exit, references the UncaughtExceptionHandler, and reads the trace's frame order correctly.

for a principal

Discusses cost of stack unwinding, designing exception boundaries, and configuring thread-level uncaught handlers for resilience in production systems.

## The setup: what is the call stack? When a Java program runs, each method call is recorded on a structure called the **call stack**. A **stack frame** is created for every method invocation; it holds that method's local variables and remembers where to return when the method finishes. If `main` calls `a`, and `a` calls `b`, and `b` calls `c`, the stack (innermost on top) looks like: `c` → `b` → `a` → `main`. The method currently running is always the top frame. ## What an exception is An **exception** is an object (a subclass of `java.lang.Throwable`) that represents an abnormal event — e.g. dividing by zero (`ArithmeticException`) or calling a method on a `null` reference (`NullPointerException`). You can also create one and **throw** it explicitly with the `throw` keyword. Throwing means: stop normal execution right here and signal a problem. ## Propagation: unwinding the stack When an exception is thrown in method `c`, the JVM first checks whether the throwing statement sits inside a `try` block in `c` that has a `catch` clause matching the exception's type (the exception type, or any supertype of it). - **If yes**, that `catch` handles it; `c` continues normally after the try/catch. - **If no**, `c` is abandoned: its frame is removed from the stack (this removal is called **unwinding**), and the exception moves to the caller, `b`. The same check runs in `b`, then `a`, then `main`. This climb from innermost frame outward is **exception propagation**. The key rule: propagation goes **up the call stack, one frame at a time, innermost first**, and stops at the **first** frame with a matching handler. ## What if nobody catches it? If the exception propagates past `main` (or past the top method of any thread) with no match, it is **uncaught**. The JVM hands it to the thread's `UncaughtExceptionHandler`. The default handler prints a message like: ``` Exception in thread "main" java.lang.ArithmeticException: / by zero at C.c(Example.java:12) at B.b(Example.java:8) at A.a(Example.java:4) at Example.main(Example.java:1) ``` The **stack trace** lists the frames in the order they were unwound — top is where the exception was thrown, bottom is `main`. That thread then terminates. In a single-threaded app this ends the JVM. ## finally still runs If a frame being unwound has a `finally` block (a block guaranteed to run when leaving a `try`), that `finally` executes **during** propagation, before the exception continues upward. This is how resources get cleaned up even on the error path. ## Deriving the answer From these pieces: throw → check current frame → no match → unwind frame (run its finally) → repeat in caller → first match handles it → else uncaught handler prints the trace and the thread dies.

  • Does an uncaught exception in a worker thread stop the whole JVM?
    No. It only terminates that thread. The JVM keeps running as long as other non-daemon threads are alive. Only an uncaught exception on the last running non-daemon thread (commonly main) ends the program.
  • In what order does the stack trace print the frames?
    Top to bottom from where the exception was thrown down to the outermost caller. The first 'at' line is the throw site; the last is typically main or the thread's run method.

saying these in an interview costs you the question

  • Saying the exception goes down to the called methods — it goes UP to callers.
  • Thinking an uncaught exception always crashes the entire program (only true on the last non-daemon thread).
  • Claiming finally is skipped when an exception propagates — it runs during unwinding.
  • Believing multiple catch blocks all run — only the first matching one does.

context

open as a page

How do you rethrow a caught exception in Java while preserving its original stack trace, and what is the difference between rethrowing the same instance and wrapping it in a new exception?

level: juniorimportance: must knowfreq 62%

basics

~20 s

Use throw e; to rethrow the exact exception you caught. Because it is the same object, its stack trace stays intact. If you wrap it in a new exception, pass the original as the cause so the trace is not lost.

open as a page

What is the throws clause in Java, and what does the compiler's 'catch-or-declare' rule require?

level: juniorimportance: must knowfreq 70%

basics

~10 s

The throws clause lists exceptions a method might throw. For checked exceptions Java forces you to either handle them with try/catch or declare them with throws, so callers know to deal with them.

open as a page

What does the throw statement do in Java, and what must follow the throw keyword?

level: juniorimportance: must knowfreq 75%

basics

~20 s

throw raises an exception. After the keyword you put an object that is a Throwable (an Exception or Error). Once thrown, the current method stops normal execution and control jumps to a matching catch block, or out of the method if none catches it.

open as a page

What is the difference between `throw` and `throws` in Java?

level: juniorimportance: must knowfreq 68%

basics

~20 s

throw is a statement that raises one exception right now inside a method body. throws is part of a method's signature that declares which checked exceptions the method might pass to its caller. One acts; the other warns.

open as a page

How do finally blocks behave while an exception is propagating up the call stack?

level: middleimportance: must knowfreq 70%

basics

~20 s

As an exception travels up through methods, every finally block it passes through runs before the exception continues to the next method. This lets cleanup code execute even when the method is exiting because of an error.

open as a page

How does the throws clause interact with method overriding — what can an overriding method declare?

level: middleimportance: must knowfreq 60%

basics

~10 s

An overriding method may not declare new or broader checked exceptions than the method it overrides. It can declare the same ones, narrower subtypes, fewer, or none — but never widen the checked-exception contract.

open as a page

What is the difference between throw and throws in Java?

level: juniorimportance: should knowfreq 55%

basics

~10 s

throw is a statement that actually raises an exception right now. throws is part of a method's signature that just declares which exceptions the method might pass to its caller. One acts, one announces.

open as a page

How does the checked vs. unchecked distinction affect how an exception propagates and what the compiler requires?

level: middleimportance: should knowfreq 62%

basics

~20 s

Both kinds propagate up the stack the same way at runtime. The difference is the compiler: a checked exception must be either caught or declared with throws on every method that lets it pass through, while an unchecked exception (RuntimeException/Error) needs no declaration.

open as a page

What is 'more-precise rethrow' analysis introduced in Java 7, and how does it let a method declare narrower checked exceptions than the catch type suggests?

level: middleimportance: should knowfreq 48%

basics

~20 s

Since Java 7, if you catch a broad type like Exception but only ever throw a couple of specific checked exceptions inside the try, the compiler is smart enough to know that. So throws can list just those specific types, not the broad caught type.

open as a page

What happens when you write `throw null;` in Java, and why?

level: middleimportance: should knowfreq 55%

basics

~10 s

throw null compiles, but at runtime Java cannot raise a null exception, so it throws a NullPointerException instead. The same thing happens if a variable you throw happens to be null.

open as a page

What is the difference between rethrowing an exception, wrapping it in a new one, and how does the cause chain preserve propagation context?

level: seniorimportance: should knowfreq 55%

basics

~20 s

Rethrowing lets the same exception keep going up. Wrapping creates a new exception that carries the original as its cause, so you change the type or add context without losing the original. The cause chain keeps the full history visible in the stack trace.

open as a page

Why don't exceptions propagate across thread boundaries, and how do you observe failures from worker threads, executors, and futures?

level: seniorimportance: should knowfreq 48%

basics

~20 s

Each thread has its own call stack, so an exception can only climb its own stack — it can't jump to the thread that started it. A worker thread's uncaught exception just kills that thread. To see such failures you use Future.get, an UncaughtExceptionHandler, or CompletableFuture's error callbacks.

open as a page

When would you use a broad catch with more-precise rethrow versus a multi-catch block, and what are the trade-offs?

level: seniorimportance: should knowfreq 35%

basics

~20 s

Use multi-catch when you want to name exactly the few exception types you handle. Use a broad catch (with precise rethrow) when you want one block to log or clean up for any exception but still rethrow with a precise contract. Multi-catch is more explicit; broad catch is more convenient.

open as a page

When designing a method, how do you decide whether to catch a checked exception locally or declare it in throws?

level: seniorimportance: should knowfreq 50%

basics

~10 s

Catch it where you can actually do something useful — recover, retry, use a default, or add context. Otherwise declare it and let a higher layer that has the context to decide handle it.

open as a page

How do you re-throw a caught exception, and what is the difference between re-throwing as-is and wrapping it in a new exception?

level: seniorimportance: should knowfreq 50%

basics

~20 s

Inside a catch block you can throw the same exception again to let it keep propagating, or you can throw a new exception that includes the original as its 'cause'. Wrapping lets you raise a more meaningful exception while preserving the original stack trace.

open as a page

How does the throw statement interact with definite-assignment and unreachable-code analysis at compile time?

level: seniorimportance: nice to knowfreq 30%

basics

~20 s

Because throw never lets execution continue past it, the compiler treats code right after an unconditional throw as unreachable, which is a compile error. It also means a method ending in throw doesn't need a return, and branches that always throw count as completing for assignment checks.

open as a page

How can a method rethrow a checked exception without declaring it in its throws clause, and why is the 'sneaky throws' technique controversial?

level: principalimportance: nice to knowfreq 18%

basics

~20 s

You can trick the compiler with an unchecked generic cast so a checked exception is thrown without being declared — this is 'sneaky throws.' It works because the checked/unchecked rule is only enforced at compile time, not by the JVM. It's controversial because callers can't see or catch the exception by type.

open as a page

Are checked exceptions a good language feature? Evaluate the design tradeoffs of the catch-or-declare requirement.

level: principalimportance: nice to knowfreq 35%

basics

~20 s

They force callers to acknowledge recoverable errors, which can improve reliability. But they add boilerplate, leak across layers, and break with lambdas, so many modern designs prefer unchecked exceptions. It's a genuine tradeoff, not a settled win.

open as a page