0

I have come across a piece of code that looks like this

try
{
    try (SomeResource res = new SomeResource())
    {
        // "\(o.o)/" *BOO*
    }
}
catch (SomeException e)
{
    e.letsNotIgnoreTheException();
}

I could not think of a single reason to use two try-blocks. No one else I asked could think of one either.

I am left to wonder, whether this is simply a methode in need of some refactoring, or if there actually is some use to the outer try (especially since I found this several times, but then again, someone might have simply misunderstood the try-with-resources).

mira
  • 33
  • 3

5 Answers5

3

Given there are no extra flow-of-control or try constructs in your real code, your code is equivalent to this:

    try (SomeResource res = new SomeResource()) {
        // "\(o.o)/" *BOO*
    } catch (SomeException e) {
        e.letsNotIgnoreThisException();
    }

Please note that:

  • try-with-resources executes res.close() before exception handling
  • therefore e.letsNotIgnoreThisException() gets called after res.close()
  • any other exceptions thrown by *BOO* line must be handled (i.e. caught or declared) appropriately

The key line explaining the order of execution of resource closing and exception handling in try-with-resources is described here:

http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

quote:

Note: 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.

vikingsteve
  • 38,481
  • 23
  • 112
  • 156
0

If the outside try-catch has nothing inside besides the inner try, then it's unnecessary since you can combine them into one. However, if the outer try-catch has something else in it, the semantics may be different.

Kayaman
  • 72,141
  • 5
  • 83
  • 121
0

Disproved:

This performs differently than a single try block - the try-with-resources translates into closing the resource in a finally block, which executes after catch blocks, whereas the try-with-resources in a nested try block executes before outer catch blocks.

It could be useful if you want to close the SomeResource resource before the catch block is performed.

For example, if you were writing something into a file and on error wanted to delete that file contents and write an error message into the same file instead (dummy example, I know), you could do this by closing the resource first, then deleting the file and writing the error within a new stream / resource.

Jiri Tousek
  • 12,211
  • 5
  • 29
  • 43
  • 2
    Jiri, that was my first presumption, but I tested it and this is incorrect - try-with-resources is *not* the same as a finally block, resources get closed **before** catch and finally. Please see the text "any catch or finally block is run after the resources declared have been closed." in the oracle documentation... – vikingsteve Oct 08 '15 at 08:24
  • 1
    @vikingsteve I stand corrected, thanks for pointing that out to me. – Jiri Tousek Oct 08 '15 at 08:49
  • 1
    No worries. This actually changed my understanding, since try-with-resources is not *"technically"* the same as a finally block, although it shouldn't matter in most circumstances. I learned something new today also :) – vikingsteve Oct 08 '15 at 08:54
0

When accessing a database this pattern occurrs often - primarily to ensure resources are closed properly but also to deal with errors while processing each record without stopping the query.

    try {
        ResultSet rs = query.executeQuery();
        try {
            // Each row.
            while (rs.next()) {
                // Handle each record.
                try {
                    // One row.
                } catch (SomeException se) {
                    // Deal with exception when processing the row so we do not abort the whole query.
                }
            }
        } catch (SQLException se) {
            // Perhaps database connection went down during the iteration.
        } finally {
            // Remember to close - whatever happens.
            rs.close();
        }
    } catch (Exception ex) {
        // Probably the query is malformed or something.
        log.error("failed", ex);
    }
OldCurmudgeon
  • 64,482
  • 16
  • 119
  • 213