简体   繁体   English

有关Java中的终结器的问题

[英]Question regarding finalizers in Java

Assume that I have the following class 假设我有以下课程

   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

       }
     }

What will happen in this scenario ? 在这种情况下会发生什么? Will calling class A' finalize method will be called by garbage collector at some point? 垃圾回收器会在某个时候调用A类的finalize方法吗?

What is the different between calling it and not calling A's finalize method in the child class' finalize method if it's anyway going to be called by garbage collector ? 如果仍然要由垃圾收集器调用它,则在子类的finalize方法中调用它与不调用A的finalize方法有什么区别?

In what scenario, it is ok NOT to call its parent's finalize method in the child class? 在什么情况下,可以不在子类中调用其父级的finalize方法吗? Any example of such a scenario ? 这样的情况有什么例子吗?

First off, explicitly calling a finalize() method is just like calling any other Java method. 首先,显式调用finalize()方法就像调用任何其他Java方法一样。 It is never OK to not call the parent's finalize() method if your specific class is overriding the finalize() method. 如果您的特定类覆盖了finalize()方法,则永远不要不调用父级的finalize()方法。 Of course, if you implement the finalizer guardian pattern , you don't need to explicitly call the parent finalizer in your subclass. 当然,如果实现finalizer的守护者模式 ,则无需在子类中显式调用父finalizer。

BTW, don't rely on finalize() methods for cleaning up resources which can be cleared explicitly (like closing file handles etc.) since finalizers are non-deterministic. 顺便说一句,因为finalize()是不确定的,所以不要依赖finalize()方法来清理可以显式清除的资源(如关闭文件句柄等)。 Also, take a look at the presentation by Bob Lee for using Phantom references in place of finalizers. 另外,请看Bob Lee演示 ,它使用Phantom引用代替了终结器。

You should always call super.finalize() to prevent resource leak. 您应该始终调用super.finalize()以防止资源泄漏。 See this and this . 看到这个这个 Garbage collector will always call finalize() at most once and due to polymorphism, only the overriden method is called explicitly. 垃圾回收器将始终最多调用一次finalize() ,由于多态性,只有显式调用的方法才被覆盖。

Note that it is even advisable to call finalize() inside finally to make sure it is called. 需要注意的是,即使最好调用finalize()finally以确保它被调用。 But I will give you even better advice: don't depend on finalize at all. 但是我会给您更好的建议:完全不依赖于finalize Close your resources explicitly as fast as you can and try new Java 7 feature: try with resource . 尽可能快地显式关闭资源,然后尝试Java 7的新功能: 尝试使用resource

No, only B 's finalize method will be called if you do not explicitly use super.finalize() just like any other method call. 不,如果您不像其他任何方法调用那样显式使用super.finalize() ,则仅将调用B的finalize方法。

However you should note that it's not a good practice to not call the superclass's finalize method. 但是,您应该注意,不调用超类的finalize方法不是一个好习惯。 You might inadvertently miss closing a resource or something. 您可能会无意间错过了关闭资源或其他操作的机会。

To answer your questions, 为了回答您的问题,

  1. Garbage collector will call finalize() method at some point of time but that's not guaranteed. 垃圾收集器会在某个时间点调用finalize()方法,但这不能保证。

  2. Garbage collect will call the finalize() only on the current object. 垃圾回收只会在当前对象上调用finalize()。 So calling finalize() on B will NOT call finalize() on A unless explicitly called using super.finalize(). 因此,除非使用super.finalize()显式调用,否则在B上调用finalize()不会在A上调用finalize()。

  3. finalize() method is called in case you want to do some clean up operation before the object is garbage collected. 如果要在垃圾回收之前执行一些清理操作,则调用finalize()方法。 Now if A and B have different implementation of finalize method and B's finalization does not depend on As then you should not call parents finalize method. 现在,如果A和B的finalize方法的实现方式不同,并且B的finalization不依赖于As,那么您不应调用父代finalize方法。 For example, A's finalize() method releases certain resources and specialized class B also releases certain resources (independent of As). 例如,A的finalize()方法释放某些资源,而专用类B也释放某些资源(独立于As)。 In the similar way there might other subclasses of A which are using the resources of A (hence not overriding A's finalize()). 以类似的方式,可能还有A的其他子类正在使用A的资源(因此不会覆盖A的finalize())。 In this case if you invoke super.finalize() from B.finalize that may cause trouble as the resources held by A are used by other subclasses. 在这种情况下,如果从B.finalize调用super.finalize(),可能会导致麻烦,因为A拥有的资源被其他子类使用。

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

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