Java Try-With-Resources

By Arvind Rai, October 11, 2018
This page will walk through Java try-with-resources example. Try-with-resources is a try statement that declares one or more resources. The special thing about try-with-resources is that it ensures that each resource is closed at the end of the statement. Try-with-resources has been introduced in Java 7. Try-with-resources closes the resource whether try block completes normally or throws exception. We need not to close resources in finally block. Try-with-resources works with auto closable resource. An auto closable resource is the resource that implements java.lang.AutoCloseable and the objects used by resource should be implementing java.io.Closeable. Resource declaration statement appears within parenthesis of try(). Try-with-resources is used in following way.
try (//Open resource connections) {
 //Use resources
} catch () {
 //Exception handling
} 
We can open multiple resources using try-with-resources statement and they are closed by try-with-resources in such order that first dependent resource is closed and then other resources are closed. It means the resource which opens connections first, will be closed at last.

Using Try-With-Resources

Before Java 7, we handle resource management using try-catch-finally block as following.
try {
//Open resource connections
//Use resources
} catch () {
//Exception handling
} finally {
//Close connections
} 
We open resource connections such as file, database in try block and use them and catch exceptions in catch block. Finally we close connections in finally block. finally block executes regardless of try block executes normally or abruptly.
Java 7 introduces try-with-resources statement using which we can declare and instantiate object within parenthesis of try(), use them within try block and connections will be closed by try-with-resources statement automatically whether try block completes normally or throws exception. We use resources with try-with-resources as following.
try (//Open resource connections) {
 //Use resources
} catch () {
 //Exception handling
} 
Now we will create a try-with-resources example with a resource. We are using StringReader in our example. StringReader is auto closable class. Find the example.
StringReaderDemo.java
package com.concretepage;
import java.io.IOException;
import java.io.StringReader;

public class StringReaderDemo {
 public static void main(String[] args) {
  String str = "Hello World! \nThis is StringReader Program.";
  int i = 0;
  try (StringReader sr = new StringReader(str)) {
   while ((i = sr.read()) != -1) {
    System.out.print((char) i);
   }
  } catch (IOException e) {
   e.printStackTrace();
  }
 }
} 
We can see that the resource StringReader has been declared within parenthesis of try(). StringReader implements java.lang.AutoCloseable and hence it is auto closable resource. After completing try block, try-with-resources will close the instance of StringReader automatically whether it completes try block normally or abruptly.
In Java 9, we can use already declared final variable as resource with try-with-resources and we need not to declare again in try(). Find the above example with Java 9 improvements.
StringReaderDemo.java
package com.concretepage;
import java.io.IOException;
import java.io.StringReader;

public class StringReaderDemo {
 public static void main(String[] args) {
  String str = "Hello World! \nThis is StringReader Program.";
  int i = 0;
  final StringReader sr = new StringReader(str);
  try (sr) {
   while ((i = sr.read()) != -1) {
    System.out.print((char) i);
   }
  } catch (IOException e) {
   e.printStackTrace();
  }
 }
} 
Before Java 7, to achieve the same goal we use finally block. To ensure that resource is closed whether try block completes normally or abruptly, we close the resource within finally block. Find the code to close the object of StringReader of above example using finally block.
public static void main(String[] args) {
   String str = "Hello World! \nThis is StringReader Program.";
   StringReader sr = new StringReader(str);
   int i=0;
   try {
      while((i=sr.read())!=-1) {
	 System.out.print((char)i);
      }
   } catch (IOException e) {
      e.printStackTrace();
   } finally {
      if (sr != null) {
	sr.close();	
      }
   }
} 

Suppressed Exceptions with Try-With-Resources

Exceptions thrown by the code in try-with-resources statement are suppressed and those exceptions can be accessed by Throwable.getSuppressed(). The try block code can throw exceptions and we can catch them using catch block but the exceptions thrown by try-with-resources statement are suppressed and they can be accessed by Throwable.getSuppressed().
When we are not using try-with-resources statement then exceptions thrown by the try block are suppressed and exceptions thrown by the finally block are not suppressed. Find the example that has a method which is using try-with-resources and another method which is using finally block to close the connections.
BufferedReaderDemo.java
package com.concretepage;
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.stream.Stream;

public class BufferedReaderDemo {
 public static void main(String[] args) {
  try {
   dataTryWithResources();
  } catch (Exception e) {
   Throwable t[] = e.getSuppressed();
   Stream.of(t).forEach(s -> System.out.println(s.getMessage()));
   e.printStackTrace();
  }

  try {
   dataFinally();
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
 
 static void dataTryWithResources() throws Exception {
  try (BufferedReader br = new BufferedReader(new FileReader("D:\\text.txt"))) {
   String str;
   while ((str = br.readLine()) != null) {
    System.out.println(str);
   }
  }
 }

 static void dataFinally() throws Exception {
  BufferedReader br = new BufferedReader(new FileReader("D:\\text.txt"));
  try {
   String str;
   while ((str = br.readLine()) != null) {
    System.out.println(str);
   }
  } finally {
   if (br != null) {
    br.close();
   }
  }
 }
} 
Inside dataTryWithResources() method, we are using try-with-resources. We have created BufferedReader object in try() and read a file in try block. If the code br.readLine() throws exception, try block will throw exception. When try-with-resources tries to close the BufferedReader connection, it is possible that it may throw exception. The exception thrown by try-with-resources will be suppressed and we can access it by using Throwable.getSuppressed(). Exception class extends Throwable. So we can also access suppressed exceptions using Exception.getSuppressed().

Inside dataFinally() method, we are using try with finally block. If the code br.readLine() throws exception, try block will throw exception and it will be suppressed and we can access it in catch block. If the code br.close() throws exception, finally block will throw exception and it will not be suppressed.

Using Try-With-Resources with Multiple Resources

We can use multiple resources with try-with-resources. Find the example using OutputStreamWriter and BufferedWriter.
MultipleResourcesDemo.java
package com.concretepage;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;

public class MultipleResourcesDemo {
 public static void main(String[] args) throws IOException {
  String str = "Hello World! \nThis is Multiple Resources Example.";

  try (Writer w = new OutputStreamWriter(System.out); 
       BufferedWriter bw = new BufferedWriter(w);) {

   bw.write(str);
  }
 }
} 

Java 9 Try-With-Resources Improvements

In Java 9, if we have already declared a final variable, we can use it directly in parenthesis of try() and we need not to declare variable again in try(). Find the example.
Java9TryWithResources.java
package com.concretepage;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;

public class Java9TryWithResources {
 public static void main(String[] args) throws IOException {
  char[] buff = new char[1024];
  String str = "Java 9 Try-With-Resources Improvements. \nHappy Learning.";

  final BufferedReader bufferReader = new BufferedReader(new StringReader(str));
  final StringWriter sw = new StringWriter();

  try (sw; 
       bufferReader) {

   int n;
   while ((n = bufferReader.read(buff)) != -1) {
    sw.write(buff, 0, n);
   }
   System.out.println(sw.toString());
  }
 }
} 
In this way we can use try-with-resources in following ways.
1. In Java 7 and Java 8.
final BufferedReader bufferReaderObj = new BufferedReader(new StringReader(str));
final StringWriter swObj = new StringWriter();
	
try(StringWriter sw = swObj;
    BufferedReader bufferReader = bufferReaderObj) {
   ------
} 
2. In Java 7 and Java 8.
try(StringWriter sw = new StringWriter();
    BufferedReader bufferReader = new BufferedReader(new StringReader(str));) {
   ------
} 
3. In Java 9.
final BufferedReader bufferReader = new BufferedReader(new StringReader(str));
final StringWriter sw = new StringWriter();
	
try(sw;
    bufferReader) {
 ------
} 

References

The try-with-resources Statement
Try-with-resources statements in JDK 9
POSTED BY
ARVIND RAI
ARVIND RAI
LEARN MORE








©2024 concretepage.com | Privacy Policy | Contact Us