finalize()
是对 JVM 的提示,即在未指定的时间执行代码可能会很好。当您希望代码神秘地无法运行时,这很好。
在终结器中执行任何重要操作(基本上除了日志记录之外的任何内容)在三种情况下也是好的:
- 你想赌其他最终确定的对象仍将处于程序的其余部分认为有效的状态。
- 您希望向具有终结器的所有类的所有方法中添加大量检查代码,以确保它们在最终确定后行为正确。
- 你想意外地复活最终确定的对象,并花很多时间试图弄清楚为什么它们不起作用,和/或为什么它们在最终发布时没有最终完成。
如果你认为你需要finize(),有时你真正想要的是一个幻像引用(在给出的示例中,它可以保存对其引用使用的连接的硬引用,并在幻像引用排队后关闭它)。这也具有它可能神秘地永远不会运行的属性,但至少它不能调用方法或复活最终确定的对象。因此,它非常适合您不需要完全关闭该连接的情况,但是您非常希望这样做,并且您类的客户端不能或不会自己调用 close(这实际上足够公平 - 如果您设计的接口需要在收集之前采取特定操作,那么拥有垃圾回收器有什么意义?这只会让我们回到malloc/free的时代。
其他时候,您需要您认为自己管理的资源来使其更加强大。例如,为什么需要关闭该连接?它最终必须基于系统提供的某种I / O(套接字,文件等),那么当最低级别的资源被gced时,为什么不能依靠系统来关闭它呢?如果另一端的服务器绝对要求您干净地关闭连接,而不仅仅是丢弃套接字,那么当有人通过运行代码的机器的电源线绊倒或中间网络熄灭时会发生什么?
免责声明:我过去曾参与过 JVM 实现。我讨厌终结器。