Java Exception Class Hierarchy
Java exceptions are organized under `Throwable`, with the two direct branches `Error` and `Exception`. Within `Exception`, `RuntimeException` represents unchecked exceptions, while other exception subclasses are generally checked.
At the top of Java's throwable hierarchy is `Throwable`. Its two direct subclasses are `Error` and `Exception`, which lets Java distinguish serious JVM or system-level problems from conditions applications commonly handle.
`Error` represents serious problems that applications generally should not try to recover from, such as `OutOfMemoryError`. `Exception` represents conditions that application code may reasonably handle, such as an `IOException` or a failed database operation.
`RuntimeException` is a subclass of `Exception`. Exceptions that extend `RuntimeException` are unchecked, so Java does not require callers to catch them or declare them with `throws`. Examples include `NullPointerException`, `IllegalArgumentException`, and `IndexOutOfBoundsException`.
Checked exceptions are subclasses of `Exception` that are not `RuntimeException`. A method that can let a checked exception escape must either catch it or declare it with `throws`. This compile-time requirement is a major distinction between checked and unchecked exceptions.
Key points
- `Throwable` is the root of Java's throwable hierarchy.
- `Error` and `Exception` directly extend `Throwable`.
- `RuntimeException` extends `Exception` and is unchecked.
- Checked exceptions must be caught or declared with `throws`.
- Unchecked exceptions include `RuntimeException` and its subclasses.
Interview questions
What is the Java exception hierarchy?
`Throwable` is the root class for objects that can be thrown and caught. It has two direct subclasses: `Error` and `Exception`. `RuntimeException` is a subclass of `Exception` and forms the main unchecked exception branch. Other `Exception` subclasses that are not `RuntimeException` are generally checked exceptions.
What makes an exception checked or unchecked in Java?
A checked exception is an `Exception` that is not a subclass of `RuntimeException`. If a checked exception can escape a method, the method must catch it or declare it using `throws`. An unchecked exception is a `RuntimeException` or one of its subclasses, so the compiler does not impose that requirement. This distinction is determined by the class hierarchy.
Why is `RuntimeException` important in the hierarchy?
`RuntimeException` separates unchecked application exceptions from checked exceptions under `Exception`. Its subclasses include common programming and argument errors such as `NullPointerException` and `IllegalArgumentException`. Java does not require methods to catch or declare these exceptions. This allows programming errors and conditions that callers are not required to recover from to propagate without compiler-enforced declarations.
Should application code catch `Error`?
Normally, application code should not catch `Error` as if it were a recoverable application condition. Errors commonly indicate serious failures such as resource exhaustion or JVM-level problems. Catching one indiscriminately can hide a failure without providing a meaningful recovery strategy. Specific infrastructure or framework code may have specialized reasons to observe certain errors, but that is different from treating `Error` as an ordinary exception.