Use try-with-resources
The try-with-resources statement is a try statement that declares one or more resources.
A resource is as an object that must be closed after the program is finished with it. The try-with-resources statement ensures that each resource is closed at the end of the statement. Any object that implements
java.lang.AutoCloseable, which includes all objects which implement
java.io.Closeable, can be used as a resource:
package java.lang;
public interface
AutoCloseable {
void close() throws Exception;
}
The Closeable interface extends the
AutoCloseable interface. The close() method of the Closeable interface throws exceptions of type
IOException while the close() method of the
AutoCloseable interface throws exceptions of type Exception. Consequently, subclasses of the
AutoCloseable interface can override this behavior of the close() method to throw specialized exceptions, such as
IOException, or no exception at all.
package java.io;
import
java.io.IOException;
public interface Closeable extends
AutoCloseable {
public void close() throws
IOException;
}
The following example reads the first line from a file. It uses an instance of
BufferedReader to read data from the file.
BufferedReader is a resource that must be closed after the program is finished with it:
static
String readFirstLineFromFile(String path) throws
IOException {
try (
BufferedReader br = new
BufferedReader(new
FileReader(path))) {
return br.readLine();
}
}
In this example, the resource declared in the try-with-resources statement is a
BufferedReader. The declaration statement appears within parentheses immediately after the try keyword. The class
BufferedReader, in Java SE 7 and later, implements the interface
java.lang.AutoCloseable. Because the
BufferedReader instance is declared in a try-with-resource statement, it will be closed regardless of whether the try statement completes normally or abruptly (as a result of the method BufferedReader.readLine throwing an
IOException).
Prior to Java SE 7, you can use a finally block to ensure that a resource is closed regardless of whether the whether the try statement completes normally or abruptly. The following example uses a finally block instead of a try-with-resources statement:
static String readFirstLineFromFileWithFinallyBlock(String path) throws
IOException {
BufferedReader br = new
BufferedReader(new
FileReader(path));
try {
return br.readLine();
} finally {
if (br != null) br.close();
}
}
However, in this example, if the methods readLine and close both throw exceptions, then the method readFirstLineFromFileWithFinallyBlock throws the exception thrown from the finally block; the exception thrown from the try block is suppressed. In contrast, in the example readFirstLineFromFile, if exceptions are thrown from both the try block and the try-with-resources statement, then the method readFirstLineFromFile throws the exception thrown from the try block; the exception thrown from the try-with-resources block is suppressed. In Java SE 7 and later, you can retrieve suppressed exceptions; see the next section for more information.
You may declare one or more resources in a try-with-resources statement. The following example makes a copy of a file, using the try-with-resources statement. There are two resources defined in the try statement, separated by a semicolon, which are automatically closed when the statement completes:
public static void copyFile(String src, String dest) throws
IOException {
try (
BufferedReader in = new
BufferedReader(new
FileReader(src));
BufferedWriter out = new
BufferedWriter(new
FileWriter(dest))) {
String line;
while((line = in.readLine()) != null) {
out.write(line);
out.write('\n');
}
} // No need to close resources in a "finally"
}
NOTE: the close() methods of resources are called in the OPPOSITE order of their creation.
NOTE: in try-with-resource statement the catch and the finally blocks are OPTIONAL.