DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Newsletter
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • How Java Apps Litter Beyond the Heap
  • Coordinating Threads Using CountDownLatch
  • Stop Writing Database Migration Scripts: Declarative Schema Sync for Java
  • Searching Kafka Without an Index: Lessons From Building Message Search for Kafdrop

Trending

  • How to Migrate From C/C++ to Rust: A Practical Guide for Embedded IoT Systems
  • Stop Writing Database Migration Scripts: Declarative Schema Sync for Java
  • Architecture Review Boards for Generative AI: A Framework for Governance, Risk Management, and Responsible Adoption
  • Testing Java and Spring Applications With Kotlin: Low-Risk to Adoption

Draft This article hasn't been published, so readers can't see it.

In moderation This article is waiting for review, so readers can't see it yet.

Deleted This article has been deleted, so readers can't see it.

  1. DZone
  2. Coding
  3. Java
  4. Java Code Bytes: Be Resourceful With Try-With-Resources

Java Code Bytes: Be Resourceful With Try-With-Resources

When implementing a business case, we have to deal with resources. Check out this post to learn how to manage resources with the try-with-resources method in Java!

By 
Gautam Deb
·
Updated Aug. 07, 18 · Analysis
Post on X (opens in a new tab) Share on LinkedIn (opens in a new tab)
33.8K Views

Join the DZone community Save articles, join the discussion, and download Refcards and Trend Reports with a free account.

Join for free Already a member? Log in

It is very common that, while implementing a business case in Java, we have to deal with resources. In this context, a resource (such as a file or socket handle) is encapsulated in an object that we must close after they are used in order to release the resource. Traditionally, the onus was on the developer to close all the resources they created to avoid dependency collisions, generally in the following finally block. Failing to do so is not a compilation error, but it can easily lead to a leakage of resource. Though modern static code analysis tools are smart enough to give you a hint, not everyone uses them, and also, those alerts can be easily overlooked.

try-with-resources was first introduced in Java 7 and is a new way to handle (closing of) resources; it makes it easier dealing with resources by automatically taking care of the closing of resources in the correct order, which was used within a try-catch block.

Let's take a business case implementation where we need to fetch a given account's status code from a database. We will first see how it is done in the traditional way and, then, with more resourceful try-with-resources. Later, we will also see a more concise version of it, which was introduced in Java 9.

Resource Handling in the Traditional Way (pre-Java 7)

// Code is simplified and kept relevant to focus on the topic in hand.
public static int getAccountStatusCodeFromDataStore_traditional(String accountId) throws SQLException {
  String accountStatusCodeQuery = getAccountStatusCodeQuery(accountId);
  Statement statement = null;
  ResultSet resultSet = null;
  try {
    statement = createStatementFromConnection();
    resultSet = statement.executeQuery(accountStatusCodeQuery);
    return getAccountStatusCodeFromResultSet(resultSet);
  } finally {
    if (resultSet != null)
      resultSet.close();
    if (statement != null)
      statement.close();
  }
}


As shown above, we have to add a finally block to deal with the closing of resource. We have to explicitly check for null before we call the close operation. Also, we have to maintain the logical order for the closing of resources. The code here is verbose; and, I have seen many cases where developers tend to forget to add the finally block for closing resource, which will lead to resource leaks.

As a side note, if exceptions are thrown here in both try block and finally block, the one thrown from finally block will suppress the other.

Resource Handling With try-with-resources in Java 7/8

The same block of code above is now implemented with try-with-resources, which will look like:

// Code is simplified and kept relevant to focus on the topic in hand.
public static int getAccountStatusCodeFromDataStore_tryWithResourcesJava7(String accountId) throws SQLException {
  String accountStatusCodeQuery = getAccountStatusCodeQuery(accountId);
  try (Statement statement = createStatementFromConnection();
       ResultSet resultSet = statement.executeQuery(accountStatusCodeQuery)) {
    return getAccountStatusCodeFromResultSet(resultSet);
  }
}


In this example, you can see that the improved concisness of the code contributes to its overall readability. The resource management is done automatically here. We can have multiple resources in the try-with-resources statement. In that case, the resource declarations should be separated by a semicolon. These resources will be automatically closed, maintaining the logic order (the one declared last will be closed first etc.).

If exceptions are thrown here, in both the try-with-resources block and try block, the one thrown from try block will suppress the other. If required, we can retrieve the suppressed exceptions by calling the Throwable.getSuppressed method from the exception thrown by the try block.

Also, a try-with-resources statement can have catch and finally blocks. Any catch or finally block is run after the resources declared have been closed.

Resource Handling With try-with-resources in Java 9

A more concise version is introduced in Java 9. If we already have a resource declared as a final or effective final, we can use them in try-with-resources without creating any new variables. This allows us to take advantage of automatic resource management. The same block of code above, now implemented with more concise try-with-resources, will look like:

// Code is simplified and kept relevant to focus on the topic in hand.
public static int getAccountStatusCodeFromDataStore_tryWithResourcesJava9(String accountId) throws SQLException {
  String accountStatusCodeQuery = getAccountStatusCodeQuery(accountId);

  // declared explicitly final
  final Statement statement = createStatementFromConnection();

  // effective final
  ResultSet resultSet = statement.executeQuery(accountStatusCodeQuery);

  try (statement; resultSet) {
    return getAccountStatusCodeFromResultSet(resultSet);
  }
}


How It Works Behind the Scenes

The AutoCloseable interface was introduced with Java 7, and it was specifically designed to work with try-with-resources statements. The Closeable interface was introduced earlier with Java 5 and was modified to extend to the AutoCloseable. They both have this abstract method close, which the resource should implement and provide a valid implementation. We can use try-with-resources to close any resource that implements either AutoCloseable or Closeable. All of the JDK resource-based classes and interfaces are modified to extend either of these interfaces, making them compatible with try-with-resources out of the box.

However, if we are dealing with a resource that doesn't implement either of AutoCloseable or Closeable, we have to follow the traditional approach for closing the resource.

Key Takeaways

try-with-resources facilitates automatic resource management with no need to write an explicit finally block to deal with closing of resources. Here is the summary of the key takeaways about try-with-resources.

  • It helps in achieving more concise and legible code.

  • We can deal with multiple resources in the try-with-resources statement.

  • In Java 7/8, these resources must be declared in try-with-resources statement. The resources declared this way are implicitly final.

  • In Java 9, we can even use pre-created resources, given that the resources referenced are declared as a final or are effective final.

  • AutoCloseable or Closeable interfaces do behind the scenes magic — they work in tandem with try-with-resources statements.

  • Most of the resource-based classes and interfaces in JDK are modified to implement either AutoCloseable or Closeable, making them compatible with try-with-resources out of the box.

  • We can have our custom resources implement either of AutoCloseable or Closeable and make them work with try-with-resources statements.

Java (programming language) Blocks

Opinions expressed by DZone contributors are their own.

Related

  • How Java Apps Litter Beyond the Heap
  • Coordinating Threads Using CountDownLatch
  • Stop Writing Database Migration Scripts: Declarative Schema Sync for Java
  • Searching Kafka Without an Index: Lessons From Building Message Search for Kafdrop

Partner Resources

×

Comments

Loading comments

The comments didn't load

Please try again in a moment.

Likes

Loading

The next likes didn't load. Please try again.

The likes didn't load

Please try again in a moment.

See who liked this

Log in or join DZone for free to see who liked this article.

Log in Join for free
  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook