Checked and unchecked exceptions
Two groups of exceptions — one important difference
All exceptions occur while a program is running, but the compiler treats them differently. For checked exceptions, it forces you to handle them explicitly or pass them further, while unchecked exceptions have no such requirement.
So checked and unchecked are primarily not about how "serious" an error is, but about whether the compiler checks how code deals with a particular exception type.
Checked: you must make a decision
A checked exception cannot simply be ignored in code where it may occur.
The method must either catch it with try-catch
or declare with throws that the exception may propagate to the calling code.
static void loadData() throws Exception {
throw new Exception("Data unavailable");
}
public static void main(String[] args) {
try {
loadData();
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
If you remove try-catch from main(),
the code will stop compiling until main() itself declares
throws Exception. The compiler requires the fate of a checked exception to be defined explicitly.
throws is also a valid decision.
Unchecked: the compiler does not force you to handle it
An unchecked exception does not have to be listed in throws
or surrounded by a try-catch block.
The program will compile even if such a failure is entirely possible at runtime.
static int getItem(int[] items, int index) {
return items[index];
}
public static void main(String[] args) {
System.out.println(getItem(new int[]{10, 20}, 5));
}
Here the compiler requires nothing, even though running the program will cause an
ArrayIndexOutOfBoundsException.
Responsibility for using a valid index remains with the program code.
This does not mean unchecked exceptions should be ignored. They can be caught when the program can genuinely recover, but it is often more useful to prevent the invalid state in advance: validate arguments, indexes, or other input conditions.
How to determine the category from the class
You already know the exception hierarchy. For checked and unchecked, it is enough to remember the boundary inside it:
- subclasses of
RuntimeExceptionare unchecked; - other subclasses of
Exceptionare checked; - subclasses of
Errorare also unchecked, but they usually represent problems that application code does not try to handle as an ordinary situation.
For example, NullPointerException,
IllegalArgumentException, and
ArrayIndexOutOfBoundsException inherit from
RuntimeException, so the compiler does not require them to be handled.
An exception that inherits directly from Exception,
on the other hand, is checked.
throws does not turn an unchecked exception into a checked one.
A RuntimeException can be explicitly listed in a method signature, but the compiler still will not force calling code to catch it or declare it further.