使用try-with-resources关闭Closeable

时间:2017-06-30 09:40:10

标签: java try-with-resources autocloseable

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

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

我的Eclipse警告我&#34;资源&#39; c&#39;应该通过try-with-resource&#34;进行管理,那么编写以下内容会更好吗?

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

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

2 个答案:

答案 0 :(得分:3)

我会忽略此警告,如果您自己管理近距离操作,则只需致电close()。空尝试资源看起来很奇怪。

考虑扩展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;
    }
}

答案 1 :(得分:1)

尝试资源的重点在于:

  • Closeable资源的开头是在try声明
  • 中完成的
  • 资源的使用位于try语句块
  • close()会自动为您调用。

所以你建议的代码:

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

...不满足try-with-resource的要点,因为你没有使用块内的资源。据推测,您的Closeable在本声明之前已经公开。

我猜你有一些代码可以打开一堆资源,完成工作,然后通过地图完成它们全部关闭。

这没关系,有时候是不可避免的。但是在可能的情况下,使用open()块中的close()使用同一方法close()finally更清晰,这样您就可以一目了然每个open()都有一个对应的close(),您可以确定始终会调用close()

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

一旦你实现了这一点,尝试使用资源只会使事情变得更整洁:

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

如果您的要求意味着您无法打开并接近相同的方法,那么只需坚持使用明确的close()并忽略警告。