简体   繁体   English

强制尝试使用资源Java 7

[英]Force try-with-resources Java 7

I have a class which implements AutoCloseable, and is intended to be used with Java 7's new try-with-resources construct. 我有一个实现AutoCloseable的类,旨在与Java 7的新try-with-resources构造一起使用。 However, I can't figure out a way to guarantee that the user of my class uses try-with-resources. 但是,我无法找到一种方法来保证我的类的用户使用try-with-resources。 If this doesn't happen, then my class won't be able to close itself, and bad things will happen. 如果没有发生这种情况,那么我的班级将无法自行关闭,并且会发生不好的事情。 Is there any way - language construct or otherwise - to enforce this? 有没有办法 - 语言构造或其他 - 来强制执行此操作? Even being able to detect whether or not I'm in a try-with-resources block so that I can throw an exception if not would be good (although a compile-time construct would be preferable). 甚至能够检测我是否在try-with-resources块中以便我可以抛出异常(如果不是)会很好(尽管编译时构造会更好)。

Thanks! 谢谢!

Unfortunately there's no way to protect yourself from user stupidity. 不幸的是,没有办法保护自己免受用户愚蠢。

You can implement the finalize method to call close ; 您可以实现finalize方法来调用close ; this way you can be sure that the resource is closed at least when the object is garbage collected, even though you can't know when (or if) that happens. 通过这种方式,您可以确保资源至少在对象被垃圾回收时关闭,即使您无法知道何时(或是否)发生这种情况。

If you can put restrictions on how your project is used, you may be able to enforce some policies using aspect oriented programming, but then you're not really using Java anymore. 如果您可以对项目的使用方式进行限制,您可以使用面向方面的编程来强制执行某些策略,但之后您就不再使用Java了。

If you really care about resource management, then using a callback idiom is the safest approach. 如果你真的关心资源管理,那么使用回调习语是最安全的方法。 You don't expose the collection, but an API that allows the end-user to handle items in the collection: 您不公开集合,而是公开允许最终用户处理集合中项目的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);
      }
    }
  }
}

You can change Callback.handle(T) to return a boolean if you want to support early exit: 如果要支持提前退出,可以更改Callback.handle(T)以返回boolean

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

If you want to stay away from defining your own callback interface, you can use Guava's Function<T, Boolean> or Predicate<T> , but note that it violates the semantics established by Guava: 如果你想远离定义自己的回调接口,你可以使用Guava的Function<T, Boolean>Predicate<T> ,但请注意它违反了Guava建立的语义:

Instances of Function are generally expected to be referentially transparent -- no side effects -- and to be consistent with equals, that is, a.equals(b) implies that function.apply(a).equals(function.apply(b)). 通常期望函数实例是引用透明的 - 没有副作用 - 并且与equals一致,即a.equals(b)意味着function.apply(a).equals(function.apply(b) )。

Instances of Predicate are generally expected to be side-effect-free and consistent with equals. 谓词的实例通常预期是无副作用的并且与equals一致。

No, there is no way, Same bad things will happen if you keep opening files or database connections and you don't close them... 不,没有办法,如果你继续打开文件或数据库连接并且你没有关闭它们会发生同样的坏事......

If the sensible resources can be used and discarted within the scope of one method call, you can open/close every time your api is called, if not, then just have well documented the behaviour. 如果可以在一个方法调用的范围内使用和放弃敏感资源,则可以在每次调用api时打开/关闭,如果没有,则只需记录好行为。

Your class might also register a shutdown hook so you can at least close your resources when the jvm is going down, but I see this as a bad practice for a library anyway. 你的类也可能注册一个关闭钩子,所以你可以在jvm关闭时至少关闭你的资源,但我认为这对于一个库而言是一种不好的做法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM