What is the difference between checked and unchecked exceptions?
Quick Answer
Checked exceptions (subclasses of Exception, excluding RuntimeException) represent recoverable conditions the compiler forces callers to handle or declare via throws — e.g., IOException. Unchecked exceptions (subclasses of RuntimeException, plus all Errors) represent programming errors or unrecoverable conditions and aren't checked by the compiler — e.g., NullPointerException, IllegalArgumentException.
Detailed Answer
Java splits exceptions into two categories, enforced differently by the compiler:
- Checked exceptions: subclasses of
Exceptionthat are notRuntimeException. The compiler forces every caller to eithercatchthem or declare them in athrowsclause — the idea being they represent recoverable, expected failure conditions (a file not found, a network timeout) that calling code should consciously plan for.
void readFile(String path) throws IOException {
Files.readString(Path.of(path)); // IOException must be declared or caught
}
- Unchecked exceptions: subclasses of
RuntimeException(NullPointerException,IllegalArgumentException,IndexOutOfBoundsException) — and allErrors. The compiler does not require handling them; they typically represent programming bugs or conditions you're not expected to recover from gracefully.
void divide(int a, int b) {
return a / b; // ArithmeticException is unchecked — no throws needed
}
This design is genuinely controversial in the Java community: checked exceptions can lead to noisy throws clauses that propagate through many layers, or to lazy catch (Exception e) {} blocks that swallow errors just to satisfy the compiler. Many modern Java libraries and frameworks (Spring, most of the JDK's newer APIs) deliberately favor unchecked exceptions even for "recoverable" conditions, leaving the checked-vs-unchecked decision to the developer's judgment about the calling API's ergonomics rather than following the strict recoverable/unrecoverable distinction dogmatically.