3

我有一个Map<Key, Closeable>,如果从地图中删除了一个键,我想关闭Closeable. 通常我有类似的东西:

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

我的 Eclipse 警告我“资源 'c' 应该由 try-with-resource 管理”,所以只写以下内容会更好吗?

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

在我的特殊实现中,我有一个 的子类Closeable,其中close()不抛出IOException,因此不需要异常处理。

4

2 回答 2

3

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.

于 2017-06-30T14:04:26.250 回答
3

我会忽略这个警告,如果你自己管理关闭操作,那么只需调用close(). 空的 try-with-resource 看起来很奇怪。

考虑扩展 Map 以便在删除时自动执行关闭操作:

public class CloseableMap<K,V extends Closeable> extends HashMap<K,V> {

    @Override
    public R remove(K key) {
        V resource = super.remove(key);
        if (resource != null) {
            resource.close();
        }
        return resource;
    }
}
于 2017-06-30T10:11:58.740 回答