Java checked vs unchecked exceptions explained
Exception hierarchy, Throwable, Error, checked exceptions, unchecked exceptions, RuntimeException, throws declaration, compiler enforcement, common exceptions
Exception Hierarchy
Java divides all throwable problems into two categories: exceptions the compiler makes you handle, and exceptions you may choose to ignore.
Hierarchy at a Glance
Throwable
├── Error // JVM-level, do not catch (OutOfMemoryError)
└── Exception
├── IOException // checked — must handle or declare
├── SQLException // checked
└── RuntimeException // unchecked — optional to handle
├── NullPointerException
├── ArrayIndexOutOfBoundsException
└── IllegalArgumentException
Checked Exception — Compiler Enforced
import java.io.FileReader;
import java.io.IOException;
public void readFile(String path) throws IOException {
FileReader fr = new FileReader(path); // IOException possible
fr.close();
}
If you neither catch IOException nor declare throws IOException, the compiler rejects the code. This forces callers to confront recoverable failures.
Unchecked Exception — Optional Handling
public int divide(int a, int b) {
return a / b; // ArithmeticException if b == 0 — no throws required
}
Design rule: Use checked exceptions for conditions the caller can realistically recover from — file not found, network timeout, invalid input format. Use unchecked for programming mistakes — null dereference, bad array index, violated invariants. These should be fixed, not caught everywhere.
Never catch Error or Throwable directly. Errors indicate JVM-level failures that no application code can meaningfully recover from.
