Java try-with-resources example
This article shows you how to use try-with-resources
in Java.
Table of contents:
- 1 Java try-with-resources before and after
- 2. try-with-resources with single resource
- 3. try-with-resources with multiple resources
- 4. Custom resource with AutoCloseable interface
- 5. Resource open and closing order
- 6. Java 9 – final or effectively final variables
- Download Source Code
- References
1 Java try-with-resources before and after
Review a Java file copy example. Before Java 7, we manually used the try-finally
block to ensure that resources were closed.
public static void copyFilePlainJava(String from, String to)
throws IOException {
InputStream inStream = null;
OutputStream outStream = null;
try {
inStream = new FileInputStream(new File(from));
outStream = new FileOutputStream(new File(to));
byte[] buffer = new byte[1024];
// if this throws exception
int length;
while ((length = inStream.read(buffer)) > 0) {
outStream.write(buffer, 0, length);
outStream.flush();
}
} finally {
// if this throws exception
if (inStream != null)
inStream.close();
// this has a leak
if (outStream != null)
outStream.close();
}
}
However, this example might have a resource leak; if the while
copy bytes process throws an exception, and the inStream.close()
throws an exception, then the outStream
has a resource leak and causes a performance issue. We can solve this by wrapping the close stream with another layer of try-catch, but it’s too lengthy and error-prone.
In Java 7, we can use try-with-resources
to ensure resources after the try block are automatically closed. And any exceptions thrown from the try-with-resources
statement will be suppressed. Review the below try-with-resources
example.
public static void copyFilePlainJava(String from, String to) throws IOException {
// try-with-resources
try (InputStream inStream = new FileInputStream(new File(from));
OutputStream outStream = new FileOutputStream(new File(to))) {
byte[] buffer = new byte[1024];
int length;
while ((length = inStream.read(buffer)) > 0) {
outStream.write(buffer, 0, length);
outStream.flush();
}
}
}
The try-with-resources
is clean, with less code and fewer bugs, and the resources automatically close after the try block.
2. try-with-resources with single resource
Below is a classic old Java BufferedReader
to open and read a file and print it out line by line.
package com.mkyong;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class TestApp {
public static void main(String[] args) {
BufferedReader br = null;
String line;
try {
br = new BufferedReader(new FileReader("c:\\testing.txt"));
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (br != null) br.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
In Java 7 and above, we rewrite the above classic BufferedReader
code with the try-with-resources
like below:
package com.mkyong.java18;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class TestApp {
public static void main(String[] args) {
String line;
try (BufferedReader br = new BufferedReader(
new FileReader("c:\\testing.txt"))) {
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
3. try-with-resources with multiple resources
We can use the semicolon :
to declare multiple resources in a try-with-resources
block. The multiple resources are automatically closed after the try block.
// try-with-resources
try (InputStream inStream = new FileInputStream(new File(from));
OutputStream outStream = new FileOutputStream(new File(to))) {
byte[] buffer = new byte[1024];
int length;
while ((length = inStream.read(buffer)) > 0) {
outStream.write(buffer, 0, length);
outStream.flush();
}
}
Yet another example.
try (FileReader fr = new FileReader(path);
BufferedReader br = new BufferedReader(fr)) {
return br.readLine();
}
3.1 JDBC example.
Below is a classic JDBC example open and closing resources to update a row.
Connection connection = null;
PreparedStatement ps = null;
try {
connection = dataSource.getConnection();
ps = connection.prepareStatement(SQL_UPDATE_POST);
ps.setInt(1, postId);
ps.executeUpdate();
} catch (Exception e) {
//
} finally {
if (ps != null) {
ps.close();
}
if (connection != null) {
connection.close();
}
}
In Java 7, we can rewrite the code with the try-with-resources
block.
try (Connection connection = dataSource.getConnection();
PreparedStatement ps = connection.prepareStatement(SQL_UPDATE_POST)) {
ps.setInt(1, postId);
ps.executeUpdate()
} catch (Exception e) {
//...
}
4. Custom resource with AutoCloseable interface
We can implement the AutoCloseable
interface to create a custom resource that will be handled by the try-with-resources
block.
package com.mkyong.io;
public class MyFileResource implements AutoCloseable {
public MyFileResource() {
// constructor
}
@Override
public void close() throws Exception {
// implements the logic to close the resource here
System.out.println("MyFileResource closed");
}
}
try (MyFileResource file = new MyFileResource()) {
// some logic
} catch (Exception e) {
throw new RuntimeException(e);
}
5. Resource open and closing order
In try-with-resources
, the resource that declares first will be closed last.
package com.mkyong.io;
public class MyFileResourceA implements AutoCloseable {
public MyFileResourceA() {
System.out.println("MyFileResourceA");
}
@Override
public void close() throws Exception {
System.out.println("MyFileResourceA closed");
}
}
package com.mkyong.io;
public class MyFileResourceZ implements AutoCloseable {
public MyFileResourceZ() {
System.out.println("MyFileResourceZ");
}
@Override
public void close() throws Exception {
System.out.println("MyFileResourceZ closed");
}
}
Run it.
try (MyFileResourceA fileA = new MyFileResourceA();
MyFileResourceZ fileZ = new MyFileResourceZ()) {
} catch (Exception e) {
throw new RuntimeException(e);
}
Output
MyFileResourceA
MyFileResourceZ
MyFileResourceZ closed
MyFileResourceA closed
Let’s reverse the resource sequence and review the output again.
try (MyFileResourceA fileZ = new MyFileResourceZ();
MyFileResourceZ fileA = new MyFileResourceA()) {
} catch (Exception e) {
throw new RuntimeException(e);
}
Output
MyFileResourceZ
MyFileResourceA
MyFileResourceA closed
MyFileResourceZ closed
6. Java 9 – final or effectively final variables
Before Java 9, we must declare a new variable for each resource.
try (InputStream inStream = new FileInputStream(new File(from));
OutputStream outStream = new FileOutputStream(new File(to))) {
//...
}
Java 9, JEP 213 allow final or effectively final variables to be used as resources in try-with-resources
statement.
InputStream inStream = new FileInputStream(from); // effectively final
OutputStream outStream = new FileOutputStream(to); // effectively final
try (inStream; outStream) {
//...
}
What is effectively final variable?
In Java, Any variable that is assigned once and only once, is effectively final
.
The below code will cause the compile-time error because the outStream
is changed after it is initialized.
InputStream inStream = new FileInputStream(from); // effectively final
OutputStream outStream = new FileOutputStream(to);
outStream = new FileOutputStream(to); // change again, not effective final
try (inStream; outStream) { // compile-time error
//...
}
Download Source Code
$ git clone https://github.com/mkyong/core-java
$ cd java-io
Sorry to say but this post is not as detailed as it should be. Please have a look at this post for more detailed explanation.
try-with-resources
try-with-resources provides clean code experience
What if we have multiple resources to close.
try (Connection connection = dataSource.getConnection();
PreparedStatement ps = connection.prepareStatement(SQL_UPDATE_POST_META)) {
you can open multiple resource in try statement
try (BufferedReader bufferedReader = new BufferedReader(new FileReader(fileName));
Scanner scanner = new Scanner(new File(fileName1))) {}
Good and succinct comparison between two approaches. However resources should not be chained in try-with-resources statement like this new BufferedReader(new FileReader(“C:\testing.txt”)). Generally it might lead to a situation when inner resource will not be closed. Take a look here for more details: http://www.softwaregeek.net/2014/01/java-7-try-with-resources-statement.html
try-with-resources and multi catch statement in Java 7 help to reduce boiler plate code in Java exception handling.
Thats a good comparison between the two approaches. If you are interested to see how the generated byte-code looks like you can check out – https://blog.srcclr.com/exception-handling-with-try-with-resources-statement-in-java-7/
exemple de mode non connect? en vb avec sql server svp
Hi,
I always liked your article but I think you missed to explain the difference incase of exception handling here. I have written a blog post explaining it in detail. Please have a look.
http://www.journaldev.com/592/try-with-resource-example-java-7-feature-for-automatic-resource-management