Exceptions and try-with-resources
Checked versus unchecked exceptions, how to catch and rethrow well, and closing resources without leaks.
The hierarchy
Everything descends from Throwable. Error signals JVM-level problems you should not catch. Exception splits into checked (must be handled or declared) and unchecked (RuntimeException and its children).
| Kind | Examples | Compiler forces handling? |
|---|---|---|
| Checked | IOException, SQLException | Yes |
| Unchecked | NullPointerException, IllegalArgumentException | No |
| Error | OutOfMemoryError, StackOverflowError | No — do not catch |
Handling
try {
int value = Integer.parseInt(text);
} catch (NumberFormatException e) {
System.err.println("Not a number: " + text);
} finally {
cleanup(); // always runs
}
// multi-catch for unrelated types
try { risky(); }
catch (IOException | SQLException e) { log(e); }⚠️
Catching
Exception broadly hides bugs. Catch the narrowest type you can actually handle, and never swallow silently — log or rethrow.try-with-resources
Anything implementing AutoCloseable can be declared inside the try parentheses and is closed automatically, in reverse order, even if the body throws.
try (var reader = Files.newBufferedReader(path);
var conn = dataSource.getConnection()) {
String line;
while ((line = reader.readLine()) != null) {
process(line);
}
} catch (IOException | SQLException e) {
throw new UncheckedIOException(new IOException(e));
}- Wrap and rethrow when the caller cannot act on a checked exception — but preserve the cause.
- Custom exceptions should extend
RuntimeExceptionfor programming errors, and be checked only when the caller can genuinely recover. Objects.requireNonNull(arg, "name")at method entry turns a vague NPE into a precise message.
FAQ
Should my API throw checked exceptions?
Default to unchecked for anything the caller cannot fix. Checked exceptions are best reserved for recoverable conditions like I/O retries.
Is printStackTrace enough?
No. Use a logging framework with levels, and include context — request id, user, inputs — so the log is actionable.
Related
Java collections Classes, records and interfaces
Last refreshed 2026-09-17.