The try-with-resources statement in Java is a powerful feature introduced in Java 7 to manage resources like files, connections, and streams automatically. It ensures that resources are closed after their operations are completed, whether the code executes successfully or an exception occurs. This eliminates the need for manual resource management and reduces the likelihood of resource leaks, which can lead to performance issues.
A resource in this context is any object that implements the AutoCloseable
or Closeable
interfaces. These resources typically hold system resources such as file handles, network sockets, or database connections. Examples include:
FileInputStream
, FileOutputStream
)Connection
in JDBC)BufferedReader
, BufferedWriter
)The try-with-resources statement simplifies resource management by ensuring that resources are closed automatically when the try block finishes, regardless of whether the execution was successful or resulted in an exception. Resources declared within the parentheses of the try
statement are closed automatically when the block exits.
try (ResourceType resource = new ResourceType()) {
// Code that uses the resource
} catch (ExceptionType e) {
// Handle exceptions
}
Here’s a breakdown:
try
keyword.close()
method on the resource.Before Java 7, you needed to close resources manually, which led to verbose and error-prone code:
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader("file.txt"));
String line = br.readLine();
System.out.println(line);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
With try-with-resources, this can be greatly simplified:
try (BufferedReader br = new BufferedReader(new FileReader("file.txt"))) {
String line = br.readLine();
System.out.println(line);
} catch (IOException e) {
e.printStackTrace();
}
In the example above:
BufferedReader
resource is automatically closed once the try block finishes.catch
block handles any potential IOException
, but even if an exception is thrown, the resource is still closed.You can manage multiple resources in a single try-with-resources statement by separating them with semicolons. Each resource is closed in the reverse order of their creation:
try (BufferedReader br = new BufferedReader(new FileReader("file.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("output.txt"))) {
String line;
while ((line = br.readLine()) != null) {
bw.write(line);
bw.newLine();
}
} catch (IOException e) {
e.printStackTrace();
}
In this case:
BufferedReader
and BufferedWriter
are closed automatically.BufferedWriter
will be closed before BufferedReader
.The try-with-resources statement relies on the AutoCloseable
interface. Any class implementing AutoCloseable
can be used with this feature. The AutoCloseable
interface defines the close()
method, which is automatically invoked when the try block finishes.
public interface AutoCloseable {
void close() throws Exception;
}
The Closeable
interface is a subinterface of AutoCloseable
, and many of the standard Java I/O classes (like FileReader
and BufferedReader
) implement Closeable
, making them compatible with try-with-resources.
In a try-with-resources block, the following can happen if an exception occurs:
close()
method), that exception is suppressed, and the original exception from the try block is thrown.getSuppressed()
method from the Throwable
class.try (CustomResource resource = new CustomResource()) {
throw new RuntimeException("Exception in try block");
} catch (Exception e) {
Throwable[] suppressed = e.getSuppressed();
System.out.println("Suppressed exceptions: " + Arrays.toString(suppressed));
}
If CustomResource
throws an exception when closing, it will be suppressed, and the exception from the try block will be propagated.
finally
block.