【问题标题】:use try-with-resources to close a Closeable使用 try-with-resources 关闭 Closeable
【发布时间】:2017-12-04 05:33:40
【问题描述】:

我有一个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,因此不需要异常处理。

【问题讨论】:

  • 它在try块之后自动调用c.close()
  • try-with-resources声明就好了,你的问题是什么?
  • 您能否提供有关 Closeable 对象的更多详细信息,为什么将它们放在地图中以及为什么在从地图中移除它们时需要关闭它们?
  • 你可以通过写map.remove(key).close()来消除c
  • @Jerry06 我知道它的作用,我只想知道最佳实践。 @YuJiaao 正如 matoni 在他的回答中所说的“空的资源尝试看起来很奇怪。”,所以我问了。 @KevinKrumwiede 你是对的,但这不是问题。 @WilQu 它用于 ServerSocket 进程。该地图保存活动的客户端连接。在断开连接或超时时,它们将从该地图中删除,并且正在监听的 Thread 将被关闭。

标签: java try-with-resources autocloseable


【解决方案1】:

try-with-resources 的要点是:

  • Closeable 资源的打开是在try 语句中完成的
  • 资源的使用在try语句块内
  • 系统会自动为您调用 close()

所以你建议的代码:

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

... 不满足 try-with-resource 的点,因为您没有使用块内的资源。大概你的Closeable在这个声明之前已经打开了。

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

这没关系,有时是不可避免的。但在可能的情况下,将open()close() 放在同一方法中会更简洁,close()finally 块中,这样您就可以一眼看出每个open() 都有一个对应的@ 987654332@ 并且您可以确保始终调用 close()

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

一旦你做到了,try-with-resources 只会让事情变得更整洁:

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

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

【讨论】:

  • 理论上资源可以永远打开,因为它是客户端-服务器通信,如果没有超时,客户端可以永远登录。
【解决方案2】:

我会忽略此警告,如果您自己管理关闭操作,请致电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;
    }
}

【讨论】:

    猜你喜欢
    • 2019-03-12
    • 2011-10-16
    • 2014-05-05
    • 2020-01-01
    • 2015-08-13
    • 2017-05-06
    • 1970-01-01
    • 2016-09-29
    • 1970-01-01
    相关资源
    最近更新 更多