6

我有一个实现 AutoCloseable 的类,旨在与 Java 7 的新 try-with-resources 构造一起使用。但是,我想不出一种方法来保证我班级的用户使用 try-with-resources。如果这不发生,那么我的班级将无法自行关闭,并且会发生不好的事情。有什么办法——语言结构或其他方式——来强制执行吗?甚至能够检测我是否在 try-with-resources 块中,这样如果不是的话我可以抛出异常(尽管编译时构造会更好)。

谢谢!

4

3 回答 3

3

不幸的是,没有办法保护自己免受用户愚蠢的影响。

您可以实现finalize调用的方法close;通过这种方式,您可以确保至少在对象被垃圾回收时关闭资源,即使您不知道何时(或是否)发生这种情况。

如果您可以限制项目的使用方式,那么您可能可以使用面向方面的编程来强制执行一些策略,但是您不再真正使用 Java。

于 2013-07-02T16:12:37.240 回答
1

如果您真的关心资源管理,那么使用回调惯用语是最安全的方法。您不公开集合,而是允许最终用户处理集合中的项目的 API:

public interface Callback<T> {
  void handle(T item);
}

public class SuperVitalVault {
  public void all(Callback<Precious> callback) {
    try (...) {
      for (Precious i : ...) {
        callback.handle(i);
      }
    }
  }
}

如果您想支持提前退出,您可以更改Callback.handle(T)为 return a :boolean

    try (...) {
      for (Precious i : ...) {
        if (callback.handle(i)) break;
      }
    }

如果你不想定义自己的回调接口,可以使用 Guava 的Function<T, Boolean>or Predicate<T>,但注意它违反了 Guava 建立的语义:

通常期望 Function 的实例是引用透明的——没有副作用——并且与 equals 一致,即 a.equals(b) 意味着 function.apply(a).equals(function.apply(b) )。

Predicate 的实例通常被认为是无副作用的并且与 equals 一致。

于 2013-12-31T22:26:23.947 回答
-1

不,没有办法,如果你一直打开文件或数据库连接并且你不关闭它们,同样的坏事也会发生......

如果可以在一个方法调用的范围内使用和丢弃合理的资源,则每次调用 api 时都可以打开/关闭,如果没有,则只需详细记录该行为即可。

您的类也可能注册一个关闭挂钩,因此您至少可以在 jvm 出现故障时关闭您的资源,但无论如何我认为这对于库来说是一种不好的做法。

于 2013-07-02T16:12:38.660 回答