Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the purpose of try-with-resources statements?

People also ask

What is the advantage of using try with resources statement?

Benefits of using try-with-resources: More readable code and easy to write. Automatic resource management. Number of lines of code is reduced.

Does try with resources need catch?

A try-with-resources statement can have catch and finally blocks just like an ordinary try statement. In a try-with-resources statement, any catch or finally block is run after the resources declared have been closed.

Can we use finally with try with resources?

Resources declared in the try part have their scope restricted to the try body. If you need access to them in the catch , use a regular try-catch statement. The finally block will always execute last. @gstackoverflow In that case, yes.


It was introduced because of some resources used in Java (like SQL connections or streams) being difficult to be handled properly; as an example, in java 6 to handle a InputStream properly you had to do something like:

InputStream stream = new MyInputStream(...);
try {
    // ... use stream
} catch(IOException e) {
   // handle exception
} finally {
    try {
        if(stream != null) {
            stream.close();
        }
    } catch(IOException e) {
        // handle yet another possible exception
    }
}

Do you notice that ugly double try? now with try-with-resources you can do this:

try (InputStream stream = new MyInputStream(...)){
    // ... use stream
} catch(IOException e) {
   // handle exception
}

and close() is automatically called, if it throws an IOException, it will be supressed (as specified in the Java Language Specification 14.20.3) . Same happens for java.sql.Connection


As stated in the documentation:

The try-with-resources statement is a try statement that declares one or more resources. A resource is an object that must be closed after the program is finished with it. The try-with-resources statement ensures that each resource is closed at the end of the statement. Any object that implements java.lang.AutoCloseable, which includes all objects which implement java.io.Closeable, can be used as a resource.

The following example reads the first line from a file. It uses an instance of BufferedReader to read data from the file. BufferedReader is a resource that must be closed after the program is finished with it:

static String readFirstLineFromFile(String path) throws IOException {
    try (BufferedReader br =
                   new BufferedReader(new FileReader(path))) {
        return br.readLine();
    }
}

In this example, the resource declared in the try-with-resources statement is a BufferedReader. The declaration statement appears within parentheses immediately after the try keyword. The class BufferedReader, in Java SE 7 and later, implements the interface java.lang.AutoCloseable. Because the BufferedReader instance is declared in a try-with-resource statement, it will be closed regardless of whether the try statement completes normally or abruptly

You can read more from here.


Update from 2017 after Java 9 release

Now with Java 9 we have more syntactic sugar and we can have a resource declared outside the try-catch block but still handled properly.

Let's take for example this Java 6 way of handling the resource:

InputStream stream = new MyInputStream(...);
try {
    // ... use stream
} catch(IOException e) {
   // handle exception
} finally {
    try {
        if(stream != null) {
            stream.close();
        }
    } catch(IOException e) {
        // handle yet another possible exception
    }
}

Here we can notice that this code is incredibly ugly as pointed out in other answers.

So the solution in Java 7 was to introduce this try-catch-with-resource:

try (InputStream stream = new MyInputStream(...)){
    // ... use stream
} catch(IOException e) {
   // handle exception
}

This notation is surely way better than the previous one, however we have a problem. If the resource (stream in this case) has been declared previously but we want to be sure that it's handled correctly in this block we need a trick like this:

InputStream stream = new MyInputStream(...)
try (InputStream stream2 = stream) {
   // do something with stream being sure that is going to be closed at the end
} catch(IOException e) {
   // handle exception
}

We can notice that this situation can be addressed only with another piece of ugly code. That's why with Java 9 the Try-With-Resources has been improved introducing a new syntax:

InputStream stream = new MyInputStream(...)
try (stream) {
   // do something with stream being sure that is going to be closed at the end
} catch(IOException e) {
   // handle exception
}

Note that this syntax will result in a compile time error for Java version 8 or minor

This is more "natural" way of writing even though in most use cases we don't need the resource outside the scope of the try block. The only restriction is that the reader variable should be effectively final or just final.


In Java, if you use a resource like input or output streams you always have to close it after using. It also can throw exceptions so it has to be in a try catch block. The closing has to be in the finally block. This is a least the way until Java 7. This has several disadvantages:

  • You'd have to check if your ressource is null before closing it
  • The closing itself can throw exceptions so your finally had to contain another try - catch
  • Programmers tend to forget to close their ressources

While the first two are mostly syntax issues, the last one is more critical. So if you use the try-with statement your code gets a lot cleaner and most importantly: Your ressource will always be closed :-)


The advantage is you need not explicitly close the resources you have defined in try-with-resources Statement. JVM will take care of it. It will automatically close those resources for you.

Generally problems developers face is to structure the try-catch-finally blocks because even in finally block where we close the resources we have to use try-catch. There are various structures of try-catch-finally statement to help resolve this issue but try-with-resources Statement will basically help you ease your coding structure logic.


Benefits of using try-with-resources:

  1. More readable code and easy to write.

  2. Automatic resource management.

  3. Number of lines of code is reduced.

  4. No need of finally block just to close the resources.

  5. We can open multiple resources in try-with-resources statement separated by a semicolon. For example, we can write following code.

    public void sampleTryWithResource() {
        try(Connection dbCon = DriverManager.getConnection("url", "user", "password");
                BufferedReader br = new BufferedReader(new FileReader("C://readfile/input.txt"));) {
            //...Your Business logic
        } catch (Exception e) {
            //...Exception Handling
        }
    }
    
  6. When multiple resources are opened in try-with-resources, it closes them in the reverse order to avoid any dependency issue. You can extend my resource program to prove that.