Appearance
Lesson 03 · try-with-resources & Custom Exceptions
Objectives
After this lesson you will be able to:
- Use try-with-resources to close
AutoCloseableresources automatically. - Explain close order and suppressed exceptions.
- Design and throw custom exceptions.
try-with-resources
Any resource implementing AutoCloseable (or Closeable) declared in the try (...) header is closed automatically — in reverse order of declaration — after the block, even on exception. No finally needed.
java
try (var in = Files.newInputStream(src);
var out = Files.newOutputStream(dst)) { // out closed first, then in
in.transferTo(out);
} // close() called automatically hereExam trap
Resources close in reverse declaration order, before any catch/finally runs. Since Java 9 you can also list an effectively final existing variable in the header (try (existingResource) { … }) instead of declaring a new one. A resource variable is implicitly final — you can't reassign it inside the block.
Suppressed exceptions
If the try body throws and close() also throws, the body's exception wins (propagates) and the close() exception is attached as a suppressed exception — retrieve it with getSuppressed().
java
try (var r = new Noisy()) { // close() throws
throw new RuntimeException("primary");
}
// Propagates "primary"; the close() exception is in primary.getSuppressed()Gotcha
This is the opposite of a finally that throws: there, the finally's exception replaces the original. With try-with-resources the primary (body) exception is preserved and the close failure is suppressed.
Custom exceptions
Extend Exception (checked) or RuntimeException (unchecked). Provide constructors that accept a message and a cause so stack traces chain.
java
class InsufficientFundsException extends RuntimeException {
InsufficientFundsException(String msg, Throwable cause) {
super(msg, cause); // chain the cause
}
}
throw new InsufficientFundsException("balance too low", sqlError);SDET note
Prefer unchecked custom exceptions for programming/precondition violations and reserve checked ones for recoverable conditions a caller should handle. In tests, assert both the type and message: assertThrows(InsufficientFundsException.class, …) and inspect getCause() when chaining matters.
Key Takeaways
- try-with-resources auto-closes any
AutoCloseable, in reverse declaration order, beforecatch/finally. Resource variables are implicitly final. - When body and
close()both throw, the body exception propagates and the close failure is a suppressed exception (getSuppressed()). - Build custom exceptions by extending
Exception(checked) orRuntimeException(unchecked); pass a cause tosuperto chain.
Lesson Quiz
In which order are resources closed?
try (A a = ...; B b = ...) { }Body throws "primary"; the resource's close() also throws. What propagates?
What interface must a try-with-resources resource implement?
Can you reassign a try-with-resources resource variable inside the block?
How do you preserve the original error when throwing a custom exception?
Next: Module 04 Mini-Exam. Run the matching code in labs/src/main/java/com/jse21/m04_exceptions/.