我没有在应用程序中使用finalize方法,但是这个问题出于好奇。
假定类中有finalize方法,我想记录一条警告消息,提示未调用finalize。
如何执行此操作?
任何提示?
答案 0 :(得分:1)
两种可能性-无论哪种情况,都需要一个单例集合。
1)构造每个对象时,将一个唯一的键(字符串)标识该对象-(但不是对象本身!)到集合中。调用终结器时,将其密钥从集合中删除。
在任何给定时间,集合中都有未完成的实例。
2)好吧,如果您确实愿意,可以将对象本身添加到集合中,但是该集合必须是正确引用类的集合。这比较困难,需要做一点研究-查看参考类(WeakReference / PhantomReference / ??)。我已经有好几年没有看过它们了,忘记了到底是哪个做的,但这正是Reference类所做的工作。
请注意2,我认为遍历参考集合可能会使死的类复活或阻止收集。
这两个警告的原因是,如果您将引用存储在普通集合中,则它将永远不符合收集条件,因此不会调用终结器。
答案 1 :(得分:0)
根据JLS 12.6. Finalization of Class Instances,JVM保证在处置对象之前将调用该方法:
Java编程语言没有指定终结器被调用的时间,只是说它将在重用对象的存储之前发生。
您正试图证明JVM不遵循JLS,这将是一个错误。
查看Azul Zulu OpenJDK 11的源代码,我们可以看到终结是通过java.lang.ref.Finalizer
对象运行的,而该对象又使用jdk.internal.misc.JavaLangAccess.invokeFinalize(Object)
方法来调用Object.finalize()
。
JavaLangAccess
获得 jdk.internal.misc.SharedSecrets
实例,该实例允许设置JavaLangAccess
的自定义实例。也许您可以使用JavaLangAccess
方法中的其他日志记录来创建自己的invokeFinalize()
实例?