Managing the life cycle of resources in Java 7: the new try-with-resources block


Java 7 includes a small language change to handle the destruction of resources in a try statement. The new code block, known as try-with-resources, looks like this:

try (MyResource myResource = new MyResource()) {
   // use myResource

MyResource is a class that implements java.lang.AutoCloseable. The Java Virtual Machine will call myResource.close() whenever the program leaves the try block (whether it exits normally or after throwing an exception).

Using well-known patterns for managing the lifecycle of resources helps in writing code that is readable, robust and maintainable. Until now, Java has lacked a consistent, built-in mechanism to do this. Programming in a garbage-collected language like Java also requires the programmer to manually dispose some objects such as files, sockets or database handlers. And relying on the garbage collector to do this (by implementing the finalize() method) is generally a bad idea--the garbage collector is non-deterministic! The most common way to handle this before Java 7 would be a try-finally block:

MyResource myResource = new MyResource();
try {
   // use myResource
} finally {

Other languages had resolved this problem before. In C++ it's common to use the idiom known as "Resource Acquisition is Initialization" (RAII). RAII means that the programmer associates a new object in the stack with any resource requiring clean-up. The destructor of this object takes care of releasing the resource. Another example is C#, where programmers already benefited from the using statement, almost identical to the new Java try-with-resources block.

Here at RTI we realized that this little new Java feature goes a long way toward making your code cleaner. In the Request-Reply API, part of RTI Connext Messaging, you can wrap resources that you need to return to the middleware in a try-with-resources block. For example, reading loaned data from a Requester is as simple as:

import com.rti.connext.infrastructure.*;
import com.rti.connext.requestreply.*;
import myTypeSupport.RequestType;
import myTypeSupport.ReplyType;

Requester<RequestType, ReplyType> requester = ...;
RequestType request = ...;

try (Sample.Iterator<ReplyType> dataSamples = requester.receiveReplies()) {
    while(dataSamples.hasNext()) {
        Sample<ReplyType> dataSample =;
        System.out.println("Received a new reply: " + dataSample.getData());

When your application exits the try block, it automatically calls the Sample.Iterator.close() operation, which then returns the loaned data to the middleware (the equivalent to DataReader.return_loan(), in the Data Distribution Service (DDS) API).

Simple and elegant.

Getting Started with Connext

Connext® is the world's leading implementation of the Data Distribution Service (DDS) standard for Real-Time Systems. Try a fully-functional version of Connext for 30 days.

Free Trial