Checked vs Unchecked Exceptions in Java — Hierarchy, Compiler Rules, and Modern Design Guidance
Fast recall
Quick revision
Core answer
Exception (not RuntimeException) — the compiler forces callers to catch or declare them (throws). Examples: IOException, SQLException. Unchecked exceptions are subclasses of RuntimeException — no compiler enforcement. Examples: NullPointerException, IllegalArgumentException. Design rule: checked when the caller has a distinct recovery path (retry, fallback); unchecked for programming errors or when callers have no meaningful response. Modern frameworks (Spring, JPA, Hibernate) wrap checked SQLException into unchecked DataAccessException because most callers can't recover and throws clauses pollute the API.Whether the candidate can articulate the compiler-enforcement difference, knows the hierarchy precisely, and understands modern frameworks' preference for unchecked exceptions
Treating checked as 'more important' or 'more serious' — it's about recoverability, not severity. Catching unchecked exceptions like NPE to 'handle' them instead of fixing the bug
Discuss why Kotlin and Scala dropped checked exceptions entirely, the exception-translation pattern, and how Spring's `@ControllerAdvice` makes unchecked exceptions the modern default for REST APIs
Interview-ready guide
Interview answer
The split is about recoverability, not severity. Checked exceptions are the ones the compiler forces callers to acknowledge, because the designer thought callers would have a distinct recovery strategy.
Checked exceptions
- Direct subclasses of
Exception(notRuntimeException):IOException,SQLException,ParseException,InterruptedException - Compiler forces catch-or-declare — every caller must either handle them or add them to their own
throwsclause - Represent recoverable external conditions: file not found, network timeout, malformed input
Unchecked exceptions
- Subclasses of
RuntimeException:NullPointerException,IllegalArgumentException,ClassCastException - No compiler enforcement; represent programming bugs
- The right response is to fix the code, not catch and hide the bug
Errors
OutOfMemoryError,StackOverflowError— JVM-level failures; almost never catch them
Why the industry shifted toward unchecked
throwsclauses metastasize across wide APIs — every method that might touch a database ends up withthrows SQLException- Streams and lambdas don't accept checked exceptions cleanly —
Functioncan't throwIOException - Spring wraps
SQLExceptionintoDataAccessException(unchecked) so service code stays clean - Kotlin and Scala dropped checked exceptions entirely
Recommendation: In a modern REST service, default to unchecked custom exceptions (with preserved causes) plus a @ControllerAdvice global handler that maps them to structured HTTP responses. Reserve checked for narrow libraries where callers truly have distinct recovery paths, and always restore the interrupt flag on InterruptedException if you don't rethrow.
Checked vs Unchecked Exceptions in Java — Hierarchy, Compiler Rules, and Modern Design Guidance
Direct Answer
Checked exceptions are subclasses of Exception (not RuntimeException) — the compiler forces callers to catch or declare them (throws). Examples: IOException, SQLException. Unchecked exceptions are subclasses of RuntimeException — no compiler enforcement. Examples: NullPointerException, IllegalArgumentException. Design rule: checked when the caller has a distinct recovery path (retry, fallback); unchecked for programming errors or when callers have no meaningful response. Modern frameworks (Spring, JPA, Hibernate) wrap checked SQLException into unchecked DataAccessException because most callers can't recover and throws clauses pollute the API.
Common Mistakes & Pitfalls
Treating checked as 'more important' or 'more serious' — it's about recoverability, not severity. Catching unchecked exceptions like NPE to 'handle' them instead of fixing the bug
Check your understanding
Answer these without looking back at the article.
- Why did Kotlin drop checked exceptions entirely — what problem was it solving?
- How does Spring's `@Transactional` handle checked vs unchecked exceptions differently for rollback?
- Why can't lambdas implementing `Function<T, R>` throw `IOException`, and what are the workarounds?
- What is the exception-translation pattern and how does `DataAccessException` use it?
- When should `InterruptedException` be caught, and what is the correct handling pattern?
Related interview prep categories
1Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.