Checked vs Unchecked Exceptions
Some problems are nobody's fault and can happen to perfectly correct code: the file you need was deleted, the database is down, the network is slow. Others mean the code itself is wrong: calling a method on null, dividing by zero, reading past the end of an array. Java treats these two groups differently. For the first group, checked exceptions, the compiler makes sure you've planned for them. For the second, unchecked exceptions, it trusts you to fix the bug instead.
The Compiler Checks One Kind
import java.io.FileReader;
public class Checked {
public static void main(String[] args) {
FileReader reader = new FileReader("marks.txt");
}
}Checked.java:5: error: unreported exception FileNotFoundException; must be caught or declared to be thrown
FileReader reader = new FileReader("marks.txt");
^
1 errorFileReader's constructor declares that it may throw FileNotFoundException, a checked exception. The program won't even compile until you do one of two things:
import java.io.FileNotFoundException;
import java.io.FileReader;
public class CatchOrDeclare {
static void option1() {
try {
new FileReader("marks.txt");
} catch (FileNotFoundException e) {
System.out.println("Option 1, caught: " + e.getMessage());
}
}
static void option2() throws FileNotFoundException {
new FileReader("marks.txt");
}
public static void main(String[] args) {
option1();
try {
option2();
} catch (FileNotFoundException e) {
System.out.println("Option 2, caller caught: " + e.getMessage());
}
int n = Integer.parseInt("42");
System.out.println("Unchecked code compiles with no try: " + n);
}
}Option 1, caught: marks.txt (No such file or directory)
Option 2, caller caught: marks.txt (No such file or directory)
Unchecked code compiles with no try: 42How it works
- Catch it:
option1handles the problem itself. - Declare it:
option2addsthrows FileNotFoundException, passing the responsibility to its caller,main, which then catches it. Integer.parseIntcan throwNumberFormatException, but that's unchecked, so notryis required.
Which Is Which
| Checked | Unchecked | |
|---|---|---|
| Classes | Exception and its subclasses, except RuntimeException | RuntimeException, Error and their subclasses |
| Checked by | The compiler | Nobody; they appear at runtime |
| Usually caused by | Conditions outside your control | Bugs in the code |
| Examples | IOException, FileNotFoundException, SQLException, InterruptedException | NullPointerException, ArithmeticException, IllegalArgumentException, IndexOutOfBoundsException |
| What to do | Plan for them: catch, retry, or declare | Fix the code; validate inputs |
Why Java Has Both
The idea is simple: if a problem can happen even when your code is correct, the compiler reminds you to plan for it. If a problem only happens because of a bug, forcing a try around every division or every method call would bury the code in noise, so Java leaves those unchecked. You prevent them by writing correct code: checking for null, validating arguments, testing indexes.
Common Mistakes
Adding throws Exception to every method to silence the compiler. It hides which problems can really happen.
Catching an unchecked exception instead of fixing the bug. catch (NullPointerException e) usually means a missing null check.
Thinking "unchecked" means "can't be caught". Any exception can be caught; unchecked only means the compiler doesn't insist.
Interview Corner
What is the difference between checked and unchecked exceptions?
Checked exceptions are subclasses of Exception other than RuntimeException; the compiler enforces the catch-or-declare rule for them, so code that can throw them must either catch them or declare them with throws. They represent recoverable conditions outside the program's control, like IOException. Unchecked exceptions are RuntimeException, Error and their subclasses; the compiler doesn't enforce handling, and they usually indicate programming errors, like NullPointerException.
Is it a good idea to catch NullPointerException?
Generally no. A NullPointerException signals a bug, such as a missing null check or an uninitialized field. Fixing the code is better than catching it; catching it can hide the real problem and leave the program in an inconsistent state.
Practice
- Easy: Classify each as checked or unchecked:
FileNotFoundException,ClassCastException,SQLException,IllegalStateException,InterruptedException,StackOverflowError. - Harder: Write a method that calls
Thread.sleep(500)(which throws the checkedInterruptedException). Make it compile once by catching and once by declaring.
Key Takeaways
Was this tutorial helpful?