Table of Contents
- Table of Contents
- Introduction
- Try / Finally Approach For Closing
- Closeable
- AutoCloseable
- Try-With-Resources Syntax
- Summary
Introduction
In Java, there are resources that we need to clean up (close) once we are done using them. If we forget to do so, our applications can slowly lose memory available for new Java objects. This is called a memory leak. This may eventually cause our applications to stop working and may require a restart of the Java JVM / process in order to recover.
Try / Finally Approach For Closing
In older versions of Java, we would need to remember to not only close resources. However, it was not enough to do so later in the happy-path logic. If an exception was thrown half-way through a method, then we may never reach the close logic. Instead, we needed to do so in a finally block, so that it would be invoked, even if an exception was throw within the try block.
FileReader fileReader = null;
BufferedReader bufferedReader = null;
try {
fileReader = new FileReader("myFileName.txt");
bufferedReader = new BufferedReader(fileReader);
// TODO continue here by adding logic to read from the file
} catch (IOException e) {
// TODO do something to handle the exception
e.printStackTrace();
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException e) {
// TODO do something to handle the exception
e.printStackTrace();
}
}
if (fileReader != null) {
try {
fileReader.close();
} catch (IOException e) {
// TODO do something to handle the exception
e.printStackTrace();
}
}
}
The finally block does allow us to attempt to close the bufferedReader and fileReader objects, if they are initialized, but there is a lot of code that comes with each resource’s closing.
Closeable
Objects that require closing will often implement the Closeable interface. This interface contains one method:
void close() throws IOException
Closes this stream and releases any system resources associated with it. If the stream is already closed then invoking this method has no effect.
As noted in
AutoCloseable.close(), cases where the close may fail require careful attention. It is strongly advised to relinquish the underlying resources and to internally mark theCloseableas closed, prior to throwing theIOException.Specified by:
closein interfaceAutoCloseableThrows:
https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/io/Closeable.html#close()IOException– if an I/O error occurs
Some examples of Closeable objects that you may see frequently in Java applications are:
- BufferedInputStream,
- BufferedOutputStream,
- InputStream,
- InputStreamReader,
- FileInputStream,and
- FileOutputStream.
There are many more. The list above is far from exhaustive. However, did you catch the references to AutoCloseable in the Javadoc snippet above? That is the parent (super) interface for Closeable.
AutoCloseable
The AutoCloseable interface is one that is used by the Java try-with-resources syntax to remove some of the boilerplate.
An object that may hold resources (such as file or socket handles) until it is closed. The
https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/AutoCloseable.htmlclose()method of anAutoCloseableobject is called automatically when exiting atry-with-resources block for which the object has been declared in the resource specification header. This construction ensures prompt release, avoiding resource exhaustion exceptions and errors that may otherwise occur.
Try-With-Resources Syntax
In a try-with-resources approach, the code snippet above looks more like:
try (FileReader fileReader = new FileReader("myFileName.txt");
BufferedReader bufferedReader = new BufferedReader(fileReader);) {
// TODO continue here by adding logic to read from the file
} catch (IOException e) {
// TODO do something to handle the exception
e.printStackTrace();
}
Under the covers, Java handles the null checks and the closing of any initialized resource objects.
Summary
We need to ensure that objects using resources are closed properly. However, doing so ourselves requires a lot of boilerplate code. Using the try-with-resources syntax, we can reduce the boilerplate code and focus more on the business logic we need to implement.

Leave a comment