在Java 语言规范的§12.6中,它说:
Java 编程语言没有指定终结器将在多长时间内被调用,只是说它会在对象的存储被重用之前发生。
存储要重用的对象意味着什么?
我是否需要担心我的对象在运行时会随机发生这种情况(例如:在我使用对象时,某些东西会覆盖它)?如果是这样,我该如何防止这种情况?
在Java 语言规范的§12.6中,它说:
Java 编程语言没有指定终结器将在多长时间内被调用,只是说它会在对象的存储被重用之前发生。
存储要重用的对象意味着什么?
我是否需要担心我的对象在运行时会随机发生这种情况(例如:在我使用对象时,某些东西会覆盖它)?如果是这样,我该如何防止这种情况?
存储要重用的对象意味着什么?
我是否需要担心我的对象在运行时会随机发生这种情况(例如:在我使用对象时,某些东西会覆盖它)?
据我所知,Java 的语义并没有在任何地方暴露这种现象,所以我认为它没有任何意义,它是一个实现细节,或者,一个“信息丰富的”评论。
换句话说,这句话:
except to say that it will happen before the storage for the object is reused.
相当于什么都不说,因为它对您应该如何实现符合要求的 Java 编译器没有任何影响。
在对象被垃圾回收后,对象的存储被重用,并且该对象曾经存储的内存被用于其他事情。
由于这只发生在对象被垃圾收集之后,它永远不会发生在您仍在使用的对象上。
我认为“存储”是指用于存储对象的物理堆空间。因此,根据规范,终结器方法保证在它所属的对象尚未被覆盖时运行。
如果您正在使用一个对象(即对其具有正常引用),则它根本不符合垃圾收集条件,因此您不必担心它。
将Java“堆”存储视为一堆黑板(或“黑板”或“白板”或其他任何东西,具体取决于您的年龄和您在哪里长大)。
当您创建一个对象时,您“声明”其中一个黑板供您使用,并将您的对象数据写入它。为了跟踪它,你把一根绳子粘在它的一角,然后把那根绳子拿在手里。您将手中的那根绳子称为“参考”。
然后,您可以创建第二个对象(要求使用不同的黑板),在其上写下名称,然后将第一段字符串的末端粘贴到该名称旁边的第二个黑板上。该名称是对象中的一个字段,它引用您创建的第一个对象。
只要你有一根绳子,你可以从一个黑板到下一个黑板,到达你仍在使用的最远的黑板上,你就可以阅读你在那个遥远的黑板上写的东西。
如果您不再需要其中一个黑板,请移除它与您的手之间的那根绳子,或者在另一个黑板上您可能已经用胶带粘住的任何地方。(这是将引用设置为空。)
当黑板不再有任何通向它的绳子时,看门人可以将其擦掉,并提供给需要黑板的其他人。当他这样做时,他会将从黑板引向任何其他人的绳子移除,如果没有其他绳子到达它们,它们也会被擦除。(他还会仔细弄清楚,例如,是否有两块黑板只是相互绑在一起,没有其他绳子可以接触到它们。这些也会被擦掉。)
“终结器”是一张说明,您可以将其粘贴到黑板的一侧。就在看门人擦黑板之前,他会阅读那张纸上的说明并执行要求的任何操作。
我是否需要担心我的对象在运行时会随机发生这种情况(例如:在我使用对象时,某些东西会覆盖它)?
不,你没有。
简单来说,只有当 GC 知道您的(纯 Java)应用程序不可能再次使用它们时,这些对象才会被覆盖。
细节:
对象的存储仅在它们被垃圾收集和最终确定后才会被重用。并且一个对象只会在所有可访问的引用都丢失/覆盖/忘记之后才会被垃圾收集。如果没有可访问的对象引用,您的应用程序将无法使用它: - 它不再了解该对象。
事实上,它比这更复杂一些,因为可达性有不同的“阴影”。例如,一个等待被终结的对象是“幻影可达”的,终结器有可能再次“复活”该对象。但除非你正在编写重写的类,否则你finalize()
不需要知道这一点。需要记住的是,只有无法访问的对象才会回收它们的存储空间,纯 Java 程序在逻辑上不可能看到无法访问的对象的状态。