0 votes
in JAVA by

Auto-Closeable Classes

1 Answer

0 votes
by

Creating a resource class is a common practice, but maintaining the integrity of that resource can be a challenging prospect, especially when exception handling is involved. For example, suppose we create a resource class, Resource, and want to perform an action on that resource that may throw an exception (the instantiation process may also throw an exception):

public class Resource {
    public Resource() throws Exception {
        System.out.println("Created resource");
    }
    public void someAction() throws Exception {
        System.out.println("Performed some action");
    }
    public void close() {
        System.out.println("Closed resource");
    }
}

In either case (if the exception is thrown or not thrown), we want to close our resource to ensure there are no resource leaks. The normal process is to enclose our close() method in a finally block, ensuring that no matter what happens, our resource is closed before the enclosed scope of execution is completed:

Resource resource = null;try {
    resource = new Resource();
    resource.someAction();
} 
catch (Exception e) {
    System.out.println("Exception caught");
}
finally {
    resource.close();
}

By simple inspection, there is a lot of boilerplate code that detracts from the readability of the execution of someAction() on our Resource object. To remedy this situation, Java 7 introduced the try-with-resources statement, whereby a resource can be created in the try statement and is automatically closed before the try execution scope is left. For a class to be able to use the try-with-resources, it must implement the AutoCloseable interface:

public class Resource implements AutoCloseable {
    public Resource() throws Exception {
        System.out.println("Created resource");
    }
    public void someAction() throws Exception {
        System.out.println("Performed some action");
    }
    @Override
    public void close() {
        System.out.println("Closed resource");
    }
}

With our Resource class now implementing the AutoCloseable interface, we can clean up our code to ensure our resource is closed prior to leaving the try execution scope:

try (Resource resource = new Resource()) {
    resource.someAction();
} 
catch (Exception e) {
    System.out.println("Exception caught");
}

Compared to the non-try-with-resources technique, this process is much less cluttered and maintains the same safety (the resource is always closed upon completion of the try execution scope). If the above try-with-resources statement is executed, we obtain the following output:

Created resource
Performed some action
Closed resource

In order to demonstrate the safety of this try-with-resources technique, we can change our someAction() method to throw an Exception:

public class Resource implements AutoCloseable {
    public Resource() throws Exception {
        System.out.println("Created resource");
    }
    public void someAction() throws Exception {
        System.out.println("Performed some action");
        throw new Exception();
    }
    @Override
    public void close() {
        System.out.println("Closed resource");
    }
}

If we rerun the try-with-resources statement again, we obtain the following output:

Created resource
Performed some action
Closed resource
Exception caught

Notice that even though an Exception was thrown while executing the someAction() method, our resource was closed and then the Exception was caught. This ensures that prior to leaving the try execution scope, our resource is guaranteed to be closed. It is also important to note that a resource can implement the Closeable interface and still use a try-with-resources statement. The difference between implementing the AutoCloseable interface and the Closeable interface is a matter of the type of the exception thrown from the close() method signature: Exception and IOException, respectively. In our case, we have simply changed the signature of the close() method to not throw an exception.

Related questions

0 votes
asked Apr 21, 2020 in JAVA by Hodge
0 votes
0 votes
asked Feb 25, 2020 in JAVA by miceperry
...