Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/378.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Java7强制试用资源_Java_Try With Resources_Enforcement - Fatal编程技术网

使用Java7强制试用资源

使用Java7强制试用资源,java,try-with-resources,enforcement,Java,Try With Resources,Enforcement,我有一个实现AutoCloseable的类,打算与Java7的新的try with resources构造一起使用。但是,我无法找到一种方法来保证我的类的用户使用try-with资源。如果这种情况不发生,那么我的班级将无法自我关闭,糟糕的事情将会发生。有没有任何方法——语言构造或其他方式——来实施这一点?即使能够检测到我是否在try-with-resources块中,以便在不在的情况下抛出异常,也将是一件好事(尽管编译时构造更可取) 谢谢 不幸的是,没有办法保护自己不受用户愚蠢行为的影响 您可以

我有一个实现AutoCloseable的类,打算与Java7的新的try with resources构造一起使用。但是,我无法找到一种方法来保证我的类的用户使用try-with资源。如果这种情况不发生,那么我的班级将无法自我关闭,糟糕的事情将会发生。有没有任何方法——语言构造或其他方式——来实施这一点?即使能够检测到我是否在try-with-resources块中,以便在不在的情况下抛出异常,也将是一件好事(尽管编译时构造更可取)


谢谢

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

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


如果您可以对项目的使用方式进行限制,您可能可以使用面向方面的编程强制执行某些策略,但这样您就不再真正使用Java了。

不,不可能,如果您继续打开文件或数据库连接,而不关闭它们,同样的坏事也会发生

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


您的类可能还注册了一个关闭钩子,这样您至少可以在jvm宕机时关闭资源,但我认为这对于库来说是一个糟糕的做法。

如果您真的关心资源管理,那么使用回调习惯用法是最安全的方法。您不公开集合,而是一个允许最终用户处理集合中项目的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);
      }
    }
  }
}
如果不想定义自己的回调接口,可以使用Guava的
函数
谓词
,但请注意,它违反了Guava建立的语义:

函数的实例通常被期望是引用透明的——没有副作用——并且与equals一致,也就是说,a.equals(b)意味着Function.apply(a).equals(Function.apply(b))

谓词实例通常被认为是无副作用的,并且与equals一致


用户想要手动管理
关闭
类,而不是通过资源尝试自动关闭类,这是什么?创建一个调用
close
finalize
方法可以解决您的问题吗?不幸的是,
finalize
不能保证被调用。GC可能会决定不调用它。事实上,我想,
finalize
的不可靠性可能是引入资源试用的原因。总比什么都不调用好,而且,也不能保证你的用户必须在你的类获得GCD之前调用
close
。这就是关键所在——我正试图找出如何实现这种保证。如果我能强迫他们使用try with resources,那么我就得到了保证。在java中,使用Object.finalize()是非常不鼓励的。除非你知道自己在做什么,并且没有其他选择;)@戴维霍夫曼:我想你误解了什么。依靠GC调用finalize可能是不可取的(也是有理由的),但在某些情况下,实际实现finalize方法是防止资源泄漏的唯一选择。我同意@jarnbjo,但是我会让我的api的客户端死掉,并让他们知道api的误用,而不是让他们有不确定的行为。你错了。作为防止资源泄漏的最后一种可能,在完成相应的包装器实例时,文件和网络或数据库连接都将关闭。没有理由不为自己的目的使用相同的实现模式。感谢@jarnbjo的澄清。但我的想法是,如果你一直打开资源而不关闭它们,那么你就有漏洞了。我认为不管怎样,尽早发现漏洞总比晚一点好,如果您以某种方式保留对未关闭对象的引用,那么将不会调用finalize meethod。如果您依赖于GC,那么根据运行程序的ram和GC tunning的数量,您可能会有不确定的行为
    try (...) {
      for (Precious i : ...) {
        if (callback.handle(i)) break;
      }
    }