Java Exception Class Hierarchy Explained
Fast recall
Quick revision
Core answer
Throwable is the root type for objects Java can throw and catch. Its two direct subclasses are Error and Exception. RuntimeException is an unchecked branch under Exception; other Exception subclasses are checked unless another language rule applies. Error represents serious conditions an ordinary application usually should not try to recover from, but not every Error means the JVM itself is corrupted.Whether you know Throwable — not Exception — is the root, and can place Error, Exception, and RuntimeException correctly while explaining checked vs unchecked
Saying Exception is the root of the hierarchy, or thinking 'RuntimeException' means it happens at runtime rather than meaning 'unchecked'
Draw the tree from Throwable down, then explain that the checked/unchecked split is a compiler rule layered on top of it — Error and RuntimeException are both unchecked but for opposite reasons
Interview-ready guide
Interview answer
Throwable is the root of Java's throwable hierarchy. Its two direct subclasses are Error and Exception. Under Exception, the RuntimeException branch is unchecked; the other Exception types are checked and use catch-or-declare when they can escape. Error subclasses are also unchecked.
For example, IOException is a checked Exception, IllegalArgumentException is an unchecked RuntimeException, and OutOfMemoryError is in the Error branch. The hierarchy describes type relationships and compiler handling. It does not prove which failures are recoverable: an application may recover from some conditions in either exception category, while ordinary code usually lets serious Errors propagate.
Java Exception Class Hierarchy Explained
Direct Answer
Throwable is the root type for objects Java can throw and catch. Its two direct subclasses are Error and Exception. RuntimeException is an unchecked branch under Exception; other Exception subclasses are checked unless another language rule applies. Error represents serious conditions an ordinary application usually should not try to recover from, but not every Error means the JVM itself is corrupted.
Code Example
import java.io.IOException;
import java.nio.file.*;
public class HierarchyDemo {
// IOException is checked -> must be declared with throws
void readConfig(String path) throws IOException {
Files.readString(Path.of(path));
}
void run() {
try {
readConfig("app.properties"); // checked
int x = 10 / 0; // ArithmeticException (unchecked)
} catch (IOException e) { // Exception subclass
System.err.println("File problem: " + e.getMessage());
} catch (ArithmeticException e) { // RuntimeException subclass
System.err.println("Math problem: " + e.getMessage());
}
// OutOfMemoryError extends Error -> we deliberately never catch it
}
}
Both branches descend from Throwable, but only the checked IOException forced the throws declaration.
Common Mistakes & Pitfalls
- Calling
Exceptionthe root:Throwableis the root;ExceptionandErrorare sibling branches. - Reading runtime as timing: every thrown exception occurs during execution;
RuntimeExceptionidentifies the unchecked hierarchy branch. - Equating checked with recoverable: the compiler category does not decide what this caller can recover from.
- Catching
Throwablejust to be safe: this also catches seriousErrorvalues the code may not be able to handle. - Calling every Error a broken JVM: ordinary code usually lets Errors propagate, but the exact condition still matters.
Check your understanding
Answer these without looking back at the article.
- What is the difference between checked and unchecked exceptions?
- Can you catch an Error in Java? Should you?
- What does Throwable add over Exception?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.