有没有办法创建一个寄存器,在最后一次释放某个对象的时候会被调用?
一个示例是由物理数据文件支持的对象,一旦对象变为未引用,该文件应该被关闭而不是重命名。如果没有在该对象上显式调用“关闭”方法,那将是可能的。
我从Weak / Phantom参考区域了解的所有通知机制仅表明通知将在某个时间点发生,但没有保证何时会发生...
答案 0 :(得分:13)
简而言之,不。
Java规范明确拒绝您知道何时释放最后一个引用。 JVM实现(和优化)依赖于此。没有钩子。
答案 1 :(得分:4)
根据我的理解,我已经找了一些时间为java对象找到“析构函数”,没有办法知道你什么时候丢失了最后一个引用。 Java跟踪对象的引用,但出于性能原因,仅在垃圾回收期间更新此信息。
最接近的是在垃圾收集过程中应该调用的finalize方法,但是不能保证它会被调用。
答案 2 :(得分:4)
我认为WeakReference会做你想要的。只要弱可达(即所有强引用都消失),WeakReference就会被放入ReferenceQueue中。
请Ethan Nicholas查看此文章。
如果您担心某些引用在关闭时未到达ReferenceQueue,则保留所有对象的列表(使用WeakReferences或PhantomReferences)。添加一个关闭钩子,检查列表中是否有任何未完成的引用,并执行您需要的任何操作。
答案 3 :(得分:2)
问题是,“你如何实现这一点,没有东西持有对象的引用?”
即使您可以通过我们将调用HandleManager的服务来解决问题,HandleManager也必须创建对该对象的新引用,以传递给您的处理程序。然后,你的处理程序可以(a)存储对它的引用,这会混淆期望破坏未引用对象的HandleManager;或者(b)发布参考文献,这意味着最终的参考文献再次被释放,这意味着必须再次调用处理程序....
答案 4 :(得分:2)
如果您需要管理文件等外部资源,那么您在java中可以做的最好的就是close()函数(无论您选择什么名称)。您可以使用finalize()作为“腰带和吊带”保险单,但这具有不可预测的时间。所以你的主要防线需要是close()函数。
答案 5 :(得分:0)
这不能用Java完成 - 据我所知,它需要一个引用计数垃圾收集器。您是否考虑过根据需要打开和关闭对象的物理数据文件,而不是在对象的生命周期内保持打开状态?
答案 6 :(得分:-1)
您可以覆盖您对象中的finalize()
,但由于其他人提到的原因,这是有问题的。
对于您的具体示例,您可以查看使用File.deleteOnExit()
之类的内容,这会在VM退出后删除该文件。