tariksbl
tariksbl

Reputation: 1109

Helper to call close() if implements AutoCloseable?

Is there any helper method in the JDK or common libraries that does this:

if (resource instanceof AutoCloseable) {
    ((AutoCloseable) resource).close();
}

Just a one-liner to call an object's close() if applicable.

I know about try-with-resources, that's not applicable to this situation. And I know that not all classes that have a close() method implement AutoCloseable. But, I seem to write the above over and over..

Upvotes: 6

Views: 2120

Answers (4)

Aleksey Krichevskiy
Aleksey Krichevskiy

Reputation: 136

Was looking for solution and found this topic. Sharing my solution here since the issue still not resolved.

So the problem is that we have an object that can be potentially instance of [Auto]Closeable in runtime but this information is not available at compile time.

As an example, in my project I'm using factory that returns ClassLoader. ClassLoader does not implement AutoCloseable, but well-known URLClassLoader subclass implements AutoCloseable and should be closed. Information about actual ClassLoader type available only during runtime.

Here is the basic idea of resource wrapper that implements AutoCloseable and forwards close to resource only if it is an instance of AutoCloseable:

public class ResourceWrapper<T> implements AutoCloseable {

    private final T resource;

    public ResourceWrapper(T resource) {
        this.resource = resource;
    }

    public T getResource() {
        return resource;
    }

    @Override
    public void close() throws Exception {
        if (resource instanceof AutoCloseable) {
            ((AutoCloseable) resource).close();
        }
    }
}
try (ResourceWrapper<?> wrapper = new ResourceWrapper<>("non closeable")) {
    log.info("Resource: {}", wrapper.getResource());
}

try (ResourceWrapper<?> wrapper = new ResourceWrapper<>(new StringWriter().append("closeable"))) {
    log.info("Resource: {}", wrapper.getResource());
}

In general if factory code is under control - factory should be changed to return ResourceWrapper:

try (ResourceWrapper<Resource> wrapper = factory.getResource()) {
}

otherwise every call should be wrapped into ResourceWrapper:

try (ResourceWrapper<Resource> wrapper = new ResourceWrapper<>(factory.getResource())) {
}

Implementation and usage example in my jdoc-test project.

Upvotes: 0

rogerdpack
rogerdpack

Reputation: 66751

Here is apache commons closeQuietly adapted for AutoCloseable:

  static void closeQuietly(AutoCloseable closeable) {
    try {
      if (closeable != null) {
        closeable.close();
      }
    }
    catch (Exception swallowed) {
    }
  }

since google sent me here for that case :)

Upvotes: 0

Marco Acierno
Marco Acierno

Reputation: 14847

Edit:

Check this:

class CloserHelper
{
    public static void close(Object object)
    {
        if (object instanceof AutoCloseable)
        {
            try
            {
                ((AutoCloseable) object).close();
            }
            catch (Exception ignored) { }
        }
    }
}

I can think to something like this

class CloserHelper
{
    public static void close(AutoCloseable obj) throws Exception
    {
        obj.close();
    }
}

Then

CloserHelper.close(resource);

If the object is not a AutoCloseable you cannot just call it


If you want to ignore exceptions

class CloserHelper
{
    public static void close(AutoCloseable obj)
    {
        try
        {
            obj.close();
        }
        catch (Exception e) { }
    }
}

Upvotes: -1

Related Questions