Exception Handling
Checked vs unchecked, try/catch/finally, try-with-resources, and custom exceptions.
Deutsche Übersetzung in Arbeit
Diese Lektion ist noch nicht ins Deutsche übersetzt und wird daher auf Englisch angezeigt. Der Rest der Seite ist vollständig lokalisiert.
Auf dieser Seite
Things go wrong: files vanish, networks drop, users type nonsense. Exceptions are Java's structured way to signal and handle these problems without your whole program crashing. Handled well, they make software robust; handled poorly, they hide bugs.
What is an exception?
An exception is an object that represents something going wrong. When a problem occurs, Java throws an exception; if nothing catches it, the program stops and prints a stack trace.
A smoke alarm doesn't put out the fire - it signals a problem loudly so someone can respond. An exception is that alarm: it interrupts normal flow and hands control to code that knows how to deal with the situation. Ignore the alarm, and the building (program) evacuates (crashes).
try / catch / finally
Wrap risky code in a try block; handle failures in catch; run cleanup
in finally (which always runs, success or failure):
try {
int result = 10 / divisor; // might throw ArithmeticException
System.out.println(result);
} catch (ArithmeticException e) {
System.out.println("Can't divide by zero!");
} finally {
System.out.println("This always runs.");
}You can catch multiple types, most specific first:
try {
riskyOperation();
} catch (FileNotFoundException e) {
// handle a missing file specifically
} catch (IOException e) {
// handle any other I/O problem
}Checked vs. unchecked exceptions
Java has two families, and the difference matters:
| Checked | Unchecked (Runtime) | |
|---|---|---|
| Examples | IOException, SQLException | NullPointerException, IllegalArgumentException |
| When | Expected, recoverable problems | Programming bugs |
| Compiler | Forces you to handle or declare | Optional |
A checked exception is a forecast of rain: the compiler insists you prepare for it (handle or declare it). An unchecked exception is tripping over your own shoelaces - a bug you should just fix, so the compiler doesn't nag. Checked means "this can reasonably fail even in correct code."
A method declares checked exceptions it might throw with throws:
void readConfig() throws IOException {
Files.readString(Path.of("config.txt")); // may throw IOException
}try-with-resources: automatic cleanup
Resources like files and database connections must be closed. try-with- resources closes them automatically, even if an exception occurs:
try (var reader = Files.newBufferedReader(Path.of("data.txt"))) {
System.out.println(reader.readLine());
} // reader is closed automatically here - no finally neededAlways prefer try-with-resources
Manually closing resources in finally is verbose and easy to get wrong (what if
close() also throws?). Any resource implementing AutoCloseable works with
try-with-resources - use it for files, streams, sockets, and connections.
Custom exceptions
Create your own exception types for your domain by extending Exception
(checked) or RuntimeException (unchecked):
class InsufficientFundsException extends RuntimeException {
InsufficientFundsException(String message) {
super(message);
}
}
void withdraw(double amount) {
if (amount > balance) {
throw new InsufficientFundsException("Balance too low");
}
balance -= amount;
}Best practices
- Catch specific exceptions, not a blanket
catch (Exception e). - Never swallow silently - an empty catch block hides bugs. At minimum, log.
- Don't use exceptions for normal flow - they're for exceptional situations.
- Include context in messages: what failed and why.
- Fail fast - validate inputs early with
IllegalArgumentException.
The worst catch block
An empty catch (Exception e) {} is a bug-hiding trap: it silences problems so
they resurface later as baffling behavior. If you truly can't handle it, let it
propagate - don't bury it.
Quick check
What is the key difference between checked and unchecked exceptions?
Key takeaways
- An exception is an object signaling a problem; unhandled, it stops the program.
- Use try to wrap risky code, catch to handle failures, and finally for cleanup that always runs.
- Checked exceptions (compiler-enforced) model recoverable problems; unchecked model bugs.
- try-with-resources auto-closes AutoCloseable resources - prefer it over manual finally.
- Create custom exceptions for your domain; catch specifically, never swallow silently, and fail fast.
Next, we'll master the Collections Framework - the resizable lists, sets, and maps you'll reach for in nearly every program.