我有一个实现 AutoCloseable 的类,旨在与 Java 7 的新 try-with-resources 构造一起使用。但是,我想不出一种方法来保证我班级的用户使用 try-with-resources。如果这不发生,那么我的班级将无法自行关闭,并且会发生不好的事情。有什么办法——语言结构或其他方式——来强制执行吗?甚至能够检测我是否在 try-with-resources 块中,这样如果不是的话我可以抛出异常(尽管编译时构造会更好)。
谢谢!
我有一个实现 AutoCloseable 的类,旨在与 Java 7 的新 try-with-resources 构造一起使用。但是,我想不出一种方法来保证我班级的用户使用 try-with-resources。如果这不发生,那么我的班级将无法自行关闭,并且会发生不好的事情。有什么办法——语言结构或其他方式——来强制执行吗?甚至能够检测我是否在 try-with-resources 块中,这样如果不是的话我可以抛出异常(尽管编译时构造会更好)。
谢谢!
不幸的是,没有办法保护自己免受用户愚蠢的影响。
您可以实现finalize
调用的方法close
;通过这种方式,您可以确保至少在对象被垃圾回收时关闭资源,即使您不知道何时(或是否)发生这种情况。
如果您可以限制项目的使用方式,那么您可能可以使用面向方面的编程来强制执行一些策略,但是您不再真正使用 Java。
如果您真的关心资源管理,那么使用回调惯用语是最安全的方法。您不公开集合,而是允许最终用户处理集合中的项目的 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 一致。
不,没有办法,如果你一直打开文件或数据库连接并且你不关闭它们,同样的坏事也会发生......
如果可以在一个方法调用的范围内使用和丢弃合理的资源,则每次调用 api 时都可以打开/关闭,如果没有,则只需详细记录该行为即可。
您的类也可能注册一个关闭挂钩,因此您至少可以在 jvm 出现故障时关闭您的资源,但无论如何我认为这对于库来说是一种不好的做法。