Custom exceptions & common built-ins
◈ 4 cardsWriting your own exception types, chaining causes, and picking the right built-in.
Writing your own exception types
Custom exceptions let you communicate domain-specific errors in the type system. The choice of base class determines checkedness:
// Checked — callers MUST handle or declare
public class InsufficientFundsException extends Exception {
private final double amount;
public InsufficientFundsException(double amount) {
super("Insufficient funds: need " + amount + " more");
this.amount = amount;
}
// Constructor that chains a cause
public InsufficientFundsException(double amount, Throwable cause) {
super("Insufficient funds: need " + amount + " more", cause);
this.amount = amount;
}
public double getAmount() { return amount; }
}
// Unchecked — extend RuntimeException
public class ConfigurationException extends RuntimeException {
public ConfigurationException(String msg) { super(msg); }
public ConfigurationException(String msg, Throwable cause) { super(msg, cause); }
}
When to make an exception checked vs unchecked:
- Checked: the caller can reasonably recover —
InsufficientFundsExceptionmakes sense to catch and prompt the user. - Unchecked: the caller cannot reasonably recover, or the exception indicates a programming error —
ConfigurationExceptionat startup is usually fatal.
Modern Java (and most frameworks) lean toward unchecked exceptions for application logic; checked exceptions for I/O and transactional operations where retry/fallback is expected.
Common built-in exceptions to know for OCP:
| Exception | Unchecked? | Cause |
|---|---|---|
NullPointerException | yes | null dereference |
IllegalArgumentException | yes | invalid method argument |
IllegalStateException | yes | object in wrong state |
ClassCastException | yes | invalid downcast |
NumberFormatException | yes | bad numeric string |
StackOverflowError | yes (Error) | infinite recursion |
ArithmeticException | yes | e.g. integer divide by zero |
IOException | checked | I/O failure |
FileNotFoundException | checked | file not found (extends IOException) |
Always provide at minimum two constructors: one taking a String message, and one taking both a String and a Throwable cause — so callers can wrap underlying exceptions without losing the chain.