What an exception is, and the hierarchy
An exception is an object that describes something going wrong while the program runs: dividing by zero, reading past the end of an array, a file that is not there. When one is thrown, Java stops the current method immediately and walks back up the chain of callers looking for a matching catch. If it reaches the top of main without finding one, the program dies and prints a stack trace.
public class Main {
public static void main(String[] args) {
int[] scores = { 90, 75, 60 };
try {
System.out.println("before");
System.out.println(scores[5]); // throws here
System.out.println("never printed");
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("caught: " + e.getMessage());
}
System.out.println("program continues");
}
}before
caught: Index 5 out of bounds for length 3
program continuesRemove the try/catch and run it again: "program continues" is never printed, and you get a stack trace instead.
The hierarchy
Every exception is a subclass of Throwable. Where a class sits in this tree decides how the compiler treats it, so learning the four top classes is worth more than memorising dozens of exception names.
| Class | Means | Examples | Compiler forces you to handle it? |
|---|---|---|---|
Throwable | The root. Only Throwables can be thrown or caught | — | — |
Error | The JVM itself is in trouble. Do not catch | OutOfMemoryError, StackOverflowError | No |
Exception | A problem a program can reasonably recover from | IOException, SQLException, InterruptedException | Yes (checked) |
RuntimeException (a subclass of Exception) | Usually a bug in the calling code | NullPointerException, IllegalArgumentException, ArithmeticException, IndexOutOfBoundsException | No (unchecked) |
public class Main {
public static void main(String[] args) {
Throwable[] samples = {
new ArithmeticException(),
new java.io.IOException(),
new StackOverflowError(),
};
for (Throwable t : samples) {
String kind = (t instanceof Error) ? "Error (do not catch)"
: (t instanceof RuntimeException) ? "unchecked"
: "checked";
System.out.println(t.getClass().getSimpleName() + " -> " + kind);
}
}
}ArithmeticException -> unchecked
IOException -> checked
StackOverflowError -> Error (do not catch)