What is the difference between checked and unchecked exceptions in Java?
Checked exceptions (subclasses of Exception other than RuntimeException) must be caught or declared with throws, and the compiler enforces this. Unchecked exceptions (RuntimeException and its subclasses, plus Errors) are not checked at compile time and usually signal programming bugs.
Explain it simply
Think of booking a Tatkal ticket. There are problems you know can happen and must plan for: the server may be busy, or seats may run out. A sensible person keeps a backup plan ready. These are like checked exceptions: Java forces you to plan for them before the code even compiles.
Then there are mistakes you made yourself, such as typing the wrong date of birth. No backup plan fixes that; you should just not make the mistake. These are like unchecked exceptions: they usually mean a bug, so Java does not force you to handle them.
Example
import java.io.FileReader;
import java.io.IOException;
public class Exceptions {
// Checked: the compiler insists we catch it or declare it
static String readFirstChar(String path) throws IOException {
try (FileReader reader = new FileReader(path)) {
return String.valueOf((char) reader.read());
}
}
public static void main(String[] args) {
try {
readFirstChar("marks.txt");
} catch (IOException e) {
System.out.println("Could not read file"); // prints this if the file is missing
}
// Unchecked: compiles fine, fails at runtime
int[] scores = {90, 85};
System.out.println(scores[5]); // throws ArrayIndexOutOfBoundsException
}
}How it works
All exceptions extend Throwable, which has two branches:
Throwable
├── Error (unchecked: OutOfMemoryError, StackOverflowError)
└── Exception (checked: IOException, SQLException, InterruptedException)
└── RuntimeException (unchecked: NullPointerException, IllegalArgumentException,
ArithmeticException, ArrayIndexOutOfBoundsException)- Checked: anything under
Exceptionthat is not underRuntimeException. If a method can throw one, the compiler requires either atry/catcharound the call orthrowsin the method signature. - Unchecked:
RuntimeException, its subclasses, andError. The compiler does not force any handling. - Errors are serious JVM-level problems. Application code normally does not catch them.
Real-world use
Checked exceptions suit situations outside your control that the caller can react to: a file that may not exist, a network call that may time out, a database that may be down. Unchecked exceptions suit invalid input and broken assumptions, such as a null where one is not allowed or a negative amount in a payment. Many modern frameworks, including Spring, wrap checked database exceptions in unchecked ones so that every layer does not need throws clauses.
Common mistakes
- Catching
Exceptionand doing nothing (an empty catch block). The error disappears and debugging becomes painful. At least log it. - Thinking unchecked means "cannot be caught". You can catch any exception; the compiler just does not force you to.
- Catching
NullPointerExceptioninstead of fixing the null. - Forgetting to close resources. Use try-with-resources so files and connections close even when an exception is thrown.
What to say in the interview
"Checked exceptions are subclasses of Exception that are not RuntimeException, like IOException or SQLException. The compiler forces me to either catch them or declare them with throws, because they represent recoverable situations outside my control. Unchecked exceptions are RuntimeException and its subclasses, like NullPointerException or IllegalArgumentException, plus Errors. The compiler doesn't force handling because they usually mean a bug that should be fixed rather than caught. In my own code I use checked exceptions when the caller can meaningfully recover, and unchecked ones for invalid arguments or broken state."
Follow-up questions
- What is the difference between
throwandthrows? - What is try-with-resources and which interface does it need?
- Can you write a custom exception? Should it be checked or unchecked?
- Is
Errorchecked or unchecked? Should you catch it?
Go deeper
Read these once the basics above feel easy.
When overriding a method, the child method cannot declare broader checked exceptions than the parent. It may declare the same ones, narrower ones, or none, and it may throw any unchecked exception. This rule exists so code that calls the method through a parent reference is never surprised by a checked exception it was not told about. Also, since Java 7 you can catch several types in one block with catch (IOException | SQLException e), and try-with-resources works with any class that implements AutoCloseable.