10.1 The Throwable Hierarchy
Throwable
├── Error (JVM-level, DON'T catch: OutOfMemoryError, StackOverflowError)
└── Exception
├── RuntimeException (UNCHECKED: NullPointerException, ArithmeticException,
│ ArrayIndexOutOfBoundsException, ClassCastException,
│ NumberFormatException, IllegalArgumentException)
└── everything else (CHECKED: IOException, SQLException, FileNotFoundException,
InterruptedException, ClassNotFoundException)
10.2 Checked vs Unchecked — The Core Table
| Aspect | Checked | Unchecked |
|---|---|---|
| Inherits from | Exception (minus RuntimeException) | RuntimeException / Error |
| Compiler forces handling | Yes — catch or declare (throws) | No |
| Represents | Recoverable external failures (file missing, network down) | Programming bugs (null deref, bad index) |
| Detected | Compile time (the obligation) | Runtime only |
| Examples | IOException, SQLException | NullPointerException, ArithmeticException |
Handle-or-declare rule: a method that can throw a checked exception must either wrap it in try/catch or declare throws IOException and push the duty to its caller.
10.3 try / catch / finally Mechanics
try {
int r = a / b; // may throw ArithmeticException
} catch (ArithmeticException e) { // most specific FIRST
System.out.println("Divide by zero: " + e.getMessage());
} catch (RuntimeException | Error fatal) { // multi-catch (Java 7): one block, many types
throw fatal;
} finally {
System.out.println("finally ALWAYS runs");
}
Rules examiners probe:
- Catch blocks are tried top-down; a superclass before its subclass is a compile error ("already been caught").
- finally runs always — after normal completion, after a catch, even when try/catch contains
return(the return value is computed first, then finally runs). It is skipped only bySystem.exit()or JVM death. - A
returninside finally overrides the try's return and swallows exceptions — legal, terrible practice, favourite trick question. throwraises one exception object;throwsin the signature declares possible checked exceptions. Two different keywords.
10.4 try-with-resources (Java 7+)
Any AutoCloseable declared in the try header is closed automatically, in reverse order, whether or not an exception occurs — replacing the error-prone finally-close idiom:
try (var br = new java.io.BufferedReader(new java.io.FileReader("data.txt"))) {
System.out.println(br.readLine());
} // br.close() called for you, even on exception
If both the body and close() throw, the body's exception wins and the close failure is attached as a suppressed exception (retrievable via getSuppressed()) — an advanced-paper detail that scores full marks.
10.5 Custom Exceptions & Chaining
class InsufficientFundsException extends Exception { // checked
private final double shortfall;
InsufficientFundsException(double shortfall) {
super("Short by Rs." + shortfall);
this.shortfall = shortfall;
}
double getShortfall() { return shortfall; }
}
Extend Exception for recoverable business rules, RuntimeException for precondition violations. Exception chaining preserves the root cause: throw new ServiceException("payment failed", sqlEx); — never discard the original.
10.6 Best Practices (List These for Full Marks)
- Catch the most specific type; never blanket-catch
Exception/Throwable. - Never leave a catch block empty — log or rethrow ("exception swallowing").
- Use try-with-resources for anything closeable.
- Don't use exceptions for ordinary control flow (they cost stack-trace construction).
- Chain causes when translating exceptions across layers.
- Validate early: throw
IllegalArgumentExceptionat the API boundary.
🎯 Exam Focus
- Draw the exception hierarchy from Throwable down. Differentiate Error and Exception.
- Distinguish checked and unchecked exceptions with four examples each. What is the handle-or-declare rule?
- Differentiate
throw,throwsandfinally. When does finally NOT execute? What happens when both try and finally containreturn? - Explain try-with-resources and suppressed exceptions. Why is it superior to closing in finally?
- Write a program defining custom checked exception
InvalidAgeException, thrown when a voter's age is below 18, handled in main. - Predict the output of nested try/catch/finally blocks where an exception is thrown, caught, and a new one is thrown from finally.