Exceptions, Assertions & Logging
The Exception Hierarchy
Throwable, splitting into Error (JVM-level, don't catch), checked Exception (declared, recoverable) and unchecked RuntimeException (programming errors). The checked/unchecked line is a design decision, not an accident.Error: OutOfMemoryError, StackOverflowError — the JVM is in trouble; don't catch- Checked exceptions must be caught or declared (
throws) — for conditions callers can recover from RuntimeException(NPE, IAE, ISE, IndexOutOfBounds…) signals precondition violations — bugs- Use checked for recoverable conditions, runtime for programming errors (EJ 70)
- The stack trace is captured where the exception is constructed
| Family | Examples | Catch it? | Meaning |
|---|---|---|---|
Error | OutOfMemoryError, StackOverflowError, NoClassDefFoundError | No | JVM/resource failure — unrecoverable |
Checked Exception | IOException, SQLException, InterruptedException | Yes (or declare) | Anticipated failures of correct code |
RuntimeException | NullPointerException, IllegalArgumentException, IllegalStateException | Rarely | Bugs: violated preconditions |
The compiler enforces honesty about checked exceptions: a method that can fail in a documented way must say so in its signature, and callers must respond. That is powerful for genuinely recoverable conditions (a missing file has a story: ask the user for another) and heavy for conditions no caller can fix — which is why modern Java API design leans unchecked (Exception Best Practices).
void withdraw(BigDecimal amount) {
Objects.requireNonNull(amount, "amount"); // NPE for null args
if (amount.signum() <= 0)
throw new IllegalArgumentException("amount must be positive: " + amount);
if (closed)
throw new IllegalStateException("account closed"); // wrong object state
...
}Reuse the standard exceptions — IllegalArgumentException (bad parameter value), IllegalStateException (object not ready), NullPointerException (null where forbidden), IndexOutOfBoundsException, UnsupportedOperationException — every Java developer already knows their contracts. Custom exception types earn their existence by carrying extra data or enabling distinct handling.