Jay Taylor's notes

back to listing index

How to Specify Multiple Resources in a Single Try-With-Resources Statement - DZone Java

[web search]
Original source (dzone.com)
Tags: java howto with-statement dzone.com
Clipped on: 2019-02-08

How to Specify Multiple Resources in a Single Try-With-Resources Statement

The ability to specify multiple resources in a single try-with-resources statement is a feature introduced in Java 7. But, it can be fraught with peril if not used carefully. Read on to ensure you do this right every time.

Image (Asset 1/5) alt=

OuterResource.java

1
package dustin.examples.exceptions;
2
3
import static java.lang.System.out;
4
5
public class OuterResource implements AutoCloseable
6
{
7
   private final InnerResource wrappedInnerResource;
8
9
   public OuterResource(final InnerResource newInnerResource)
10
   {
11
      out.println("OuterResource created.");
12
      wrappedInnerResource = newInnerResource;
13
   }
14
15
   public OuterResource(
16
      final InnerResource newInnerResource,
17
      final RuntimeException exceptionToThrow)
18
   {
19
      wrappedInnerResource = newInnerResource;
20
      throw  exceptionToThrow != null
21
           ? exceptionToThrow
22
           : new RuntimeException("OuterResource: No exception provided.");
23
   }
24
25
   @Override
26
   public void close() throws Exception
27
   {
28
      out.println("OuterResource closed.");
29
   }
30
31
   @Override
32
   public String toString()
33
   {
34
      return "OuterResource";
35
   }
36
}


The two classes defined can now be used to demonstrate the difference between correctly declaring instances of each in the same try-with-resources statement in a semicolon-delimited list and incorrectly nesting instantiation of the inner resource within the constructor of the outer resource. The latter approach doesn't work as well as hoped, because the inner resource  —without a locally defined variable — is not treated as a "resource" in terms of invoking its AutoCloseable.close() method.

The next code listing demonstrates the incorrect approach for instantiating "resources" in the try-with-resources statement.

Incorrect Approach for Instantiating Resources in try-with-resources Statement

1
try (OuterResource outer = new OuterResource(
2
        new InnerResource(), new RuntimeException("OUTER")))
3
{
4
   out.println(outer);
5
}
6
catch (Exception exception)
7
{
8
   out.println("ERROR: " + exception);
9
}


When the code above is executed, the output " InnerResource created" is seen, but no output is ever presented related to the resource's closure. This is because the instance of InnerResource was instantiated within the call to the constructor of the OuterResource class and was never assigned to its own separate variable in the resource list of the try-with-resource statement. With a real resource, the implication of this is that the resource is not closed properly.

The next code listing demonstrates the correct approach for instantiating "resources" in the try-with-resources statement.

Correct Approach for Instantiating Resources in try-with-resources Statement

1
try(InnerResource inner = new InnerResource();
2
    OuterResource outer = new OuterResource(inner, new RuntimeException("OUTER")))
3
{
4
   out.println(outer);
5
}
6
catch (Exception exception)
7
{
8
   out.println("ERROR: " + exception);
9
}


When the code above is executed, the output includes both InnerResource created and InnerResource closed , because the InnerResource instance was properly assigned to a variable within the try-with-resources statement. Therefore, its close() method is properly called, even when an exception occurs during its instantiation.

The try-with-resources statement section of the Java Tutorials includes examples of correctly specifying the resources in the try-with-resources as semicolon-delimited individual variable definitions. One example shows this correct approach with java.util.zip.ZipFile and java.io.BufferedWriter. Another example shows this correct approach with instances of java.sql.Statement and java.sql.ResultSet.

The introduction of try-with-resources in JDK 7 was a welcome addition to the language that it made it easier for Java developers to write resource-safe applications that were not as likely to leak or waste resources. However, when multiple resources are declared within a single try-with-resources statement, it's important to ensure that each resource is individually instantiated and assigned to its own variable declared within the try's resource specifier list to ensure that each and every resource is properly closed. A quick way to check this is to ensure that for n, AutoCloseable is implementing resources specified in the try.There should be n-1 semicolons, separating those instantiated resources.

Get the Java IDE that understands code & makes developing enjoyable. Level up your code with IntelliJ IDEA. Download the free trial.
Topics:
java ,try-with-resources ,code ,example ,tutorial ,jls ,java 7
Like (8)

Comment (0)

Save
7,681 Views

Published at DZone with permission of Dustin Marx , DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Java Partner Resources

Red Hat Developer Program
Red Hat Developer Program