简体   繁体   中英

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. However, I can't figure out a way to guarantee that the user of my class uses 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).

Thanks!

Unfortunately there's no way to protect yourself from user stupidity.

You can implement the finalize method to call 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.

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:

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:

    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:

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)).

Instances of Predicate are generally expected to be side-effect-free and consistent with 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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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