JDK 1.7 introduced the "try-with-resources" statement [JLS 2011] §14.20.3, "try-with-resources" that makes it much easier to deal with resources that implement the java.lang.AutoCloseable
interface, including those that implement the java.io.Closeable
interface.
Using the try-with-resources statement avoids problems that can arise when closing resources with an ordinary try-catch-finally block, such as failing to close a resource because an exception is thrown as a result of closing another resource, or masking an important exception when a resource is closed.
Noncompliant Code Example
This noncompliant code example uses an ordinary try-finally block to try to close two resources. However, if closing the Bufferedreader
br
results in an exception being thrown, then the BufferedWriter
bw
will not be closed.
String inPath = ...; // input file path String outPath = ...; // output file path BufferedReader br = new BufferedReader(new FileReader(inPath)); BufferedWriter bw = new BufferedWriter(new FileWriter(outPath)); try { // process the input and produce the output } finally { close(br); close(bw); }
Compliant Solution
This compliant solution uses a try-with-resources statement which will guarantee that both br
and bw
are closed, irrespective of any exceptions being thrown during the close operations.
String inPath = ...; // input file path String outPath = ...; // output file path try ( BufferedReader br = new BufferedReader(new FileReader(inPath)); BufferedWriter bw = new BufferedWriter(new FileWriter(outPath)); ) { // process the input and produce the output }
Noncompliant Code Example
This noncompliant code example uses an ordinary try-finally block to try to close a resource. However, if there is an exception thrown both during the processing of the input and when closing the Bufferedreader
br
, then the exception thrown as a result of processing the input will be lost, and important information about that exceptional circumstance may be missed.
String inPath = ...; // input file path BufferedReader br = new BufferedReader(new FileReader(inPath)); try { // process the input and produce the output } finally { close(br); } }
Compliant Solution
This compliant solution uses a try-with-resources statement which will pass on any exception thrown during the processing of the input while still guaranteeing that br
is closed.
String inPath = ...; // input file path try ( BufferedReader br = new BufferedReader(new FileReader(inPath)); ) { // process the input and produce the output }
Applicability
Failing to use a try-with-resources statement when dealing with closeable resources may result in some resources not being closed, or important exceptions being masked, possibly resulting in a denial of service attack.