Exceptions, Assertions & Logging
Exception Doctrine (EJ 69–77)
Effective Java's chapter 10, condensed: exceptions only for exceptional conditions, checked only when callers can recover, standard types over custom, translation at layer boundaries, documentation and failure-capture always, atomicity where possible.
- Avoid unnecessary checked exceptions — they tax every caller (EJ 71)
- Document every exception thrown, with
@throws(EJ 74) - Detail messages must capture the values that caused the failure (EJ 75)
- Strive for failure atomicity: a failed call should leave the object as it was (EJ 76)
- Never let an exception escape with less information than it arrived with
| Item | Rule |
|---|---|
| 69 | Use exceptions only for exceptional conditions — never control flow |
| 70 | Checked for recoverable conditions; runtime for programming errors |
| 71 | Avoid unnecessary checked exceptions (consider Optional or state-testing) |
| 72 | Favor standard exceptions (IAE, ISE, NPE, UOE…) |
| 73 | Throw exceptions appropriate to the abstraction (translate + chain) |
| 74 | Document all exceptions thrown by each method |
| 75 | Include failure-capture information in detail messages |
| 76 | Strive for failure atomicity |
| 77 | Don't ignore exceptions |
// Useless: throw new IndexOutOfBoundsException();
// Useful — carries every value needed to reproduce:
throw new IndexOutOfBoundsException(
"index " + index + " out of bounds for range [" + lower + ", " + upper + ")");Failure atomicity (EJ 76): validate parameters before mutating (Stack.pop checks emptiness before decrementing), order operations so mutation comes last, or work on a copy and swap in on success. Callers who catch your exception will reasonably assume the object is still usable — make that true.
On checked-exception cost (EJ 71): a checked exception forces try/catch or throws on every transitive caller and breaks lambda-based composition (Functional Interfaces). Reserve it for cases where the caller genuinely can recover and no better design (Optional return, state-testing method) exists. When in doubt, unchecked.