0

假设我有以下课程

   class A {
           //some attributes 

        @override
         protected void finalize() throws Throwable {
              //do something

       }
  }


   class B extends A {

           @override
         protected void finalize() throws Throwable {
             //DONT call super.finalize() 
             //do something

       }
     }

在这种情况下会发生什么?调用类 A 的 finalize 方法会在某个时候被垃圾收集器调用吗?

如果垃圾收集器无论如何都会调用它,那么在子类的 finalize 方法中调用它和不调用 A 的 finalize 方法有什么区别?

在什么情况下,在子类中不调用其父类的 finalize 方法是可以的?这种情况的任何例子?

4

4 回答 4

2

首先,显式调用 finalize() 方法就像调用任何其他 Java 方法一样。如果您的特定类正在覆盖该方法,那么不调用父类的 finalize() 方法是绝对不行的finalize()。当然,如果你实现了终结器监护模式,你就不需要在你的子类中显式地调用父终结器。

顺便说一句,不要依赖于finalize()清理可以显式清除的资源的方法(如关闭文件句柄等),因为终结器是不确定的。此外,请查看Bob Lee 的演示文稿,该演示文稿使用 Phantom 引用代替终结器。

于 2011-07-29T12:11:25.870 回答
2

您应该始终调用super.finalize()以防止资源泄漏。看到这个这个。垃圾收集器总是finalize()最多调用一次,并且由于多态性,只有被覆盖的方法被显式调用。

请注意,甚至建议在finalize()内部调用finally以确保它被调用。但我会给你更好的建议:完全不要依赖finalize。尽可能快地明确关闭您的资源并尝试新的 Java 7 功能:尝试使用 resource

于 2011-07-29T12:17:17.740 回答
1

不,B如果您没有super.finalize()像任何其他方法调用一样显式使用,则只会调用 's finalize 方法。

但是您应该注意,不调用超类的 finalize 方法不是一个好习惯。您可能会无意中错过关闭资源或其他内容。

于 2011-07-29T12:13:31.450 回答
1

为了回答您的问题,

  1. 垃圾收集器会在某个时间点调用 finalize() 方法,但这并不能保证。

  2. 垃圾收集将仅在当前对象上调用 finalize()。所以在 B 上调用 finalize() 不会在 A 上调用 finalize(),除非使用 super.finalize() 显式调用。

  3. 如果您想在对象被垃圾收集之前进行一些清理操作,则会调用 finalize() 方法。现在如果 A 和 B 有不同的 finalize 方法实现并且 B 的终结不依赖于 As 那么你不应该调用父母的 finalize 方法。例如,A 的 finalize() 方法会释放某些资源,而专门的 B 类也释放某些资源(独立于 As)。以类似的方式,A 的其他子类可能正在使用 A 的资源(因此不会覆盖 A 的 finalize())。在这种情况下,如果您从 B.finalize 调用 super.finalize() 可能会导致麻烦,因为 A 持有的资源被其他子类使用。

于 2011-07-29T12:21:13.743 回答