繁体   English   中英

有关Java中的终结器的问题

[英]Question regarding finalizers in Java

假设我有以下课程

   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方法吗? 这样的情况有什么例子吗?

首先,显式调用finalize()方法就像调用任何其他Java方法一样。 如果您的特定类覆盖了finalize()方法,则永远不要不调用父级的finalize()方法。 当然,如果实现finalizer的守护者模式 ,则无需在子类中显式调用父finalizer。

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

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

需要注意的是,即使最好调用finalize()finally以确保它被调用。 但是我会给您更好的建议:完全不依赖于finalize 尽可能快地显式关闭资源,然后尝试Java 7的新功能: 尝试使用resource

不,如果您不像其他任何方法调用那样显式使用super.finalize() ,则仅将调用B的finalize方法。

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

为了回答您的问题,

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

  2. 垃圾回收只会在当前对象上调用finalize()。 因此,除非使用super.finalize()显式调用,否则在B上调用finalize()不会在A上调用finalize()。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM