Search code examples
javatry-with-resourcesautocloseable

use try-with-resources to close a Closeable


I have a Map<Key, Closeable> and if a key is removed from the map I want to close the Closeable. Normally I have something like:

Closeable c = map.remove(key);
c.close();

My Eclipse warns me "Resource 'c' should be managed by try-with-resource", so is it better just to write the following?

try (Closeable c = map.remove(key)) {}

In my special implementation I have a subclass of Closeable, where close() does not throw an IOException, so no exception handling is needed.


Solution

  • The point of try-with-resources is that:

    • The opening of the Closeable resource is done in the try statement
    • The use of the resource is inside the try statement's block
    • close() is called for you automatically.

    So your suggested code:

    try(Closeable c = map.remove(key)) {}
    

    ... doesn't satisfy the point of try-with-resource, since you're not using the resource inside the block. Presumably your Closeable is already open before this statement.

    I'm guessing that you have some code whereby a bunch of resources are opened, work is done, then they are all closed by working through the map.

    This is OK, and sometimes unavoidable. But it's cleaner, where possible, to have open() and close() in the same method, with the close() in a finally block, so that you can see at a glance that every open() has a corresponding close() and you can be sure that the close() is always called.

    MyCloseable c = MyCloseable.open(...);
    try{
           // do stuff with c;
    } finally {
         try {
             c.close();
         } catch (IOException e) {
             // ...
         }
    }
    

    Once you've achieved that, try-with-resources just makes things neater:

    try(MyCloseable c = MyCloseable.open(...)) {
        // do stuff with c;
    }
    

    If your requirements mean you can't get open and close into the same methods, then just stick with an explicit close() and ignore the warning.