Java基础知识点之finalize方法详解

  与toString方法类似,finalize方法也是Java中所有类中必有的方法,因为它是属于Object根类的方法,默认情况下,Java中所有的类都是Object类的子类。

  finalize方法会被自动调用调用的时机为:在销毁(回收)该对象前,finalize方法会被自动调用

  以上这句话听起来的确很抽象,什么是销毁(回收)对象呢?所谓的销毁对象就是把该对象所占用的堆内存空间给释放掉,也就是释放出更多的内存资源,释放出来的内存空间可以供别的对象使用,这一点是非常重要的

  搞清楚这个问题之后,我们就要思考,什么时候会销毁对象呢?当垃圾回收器确定不存在该对象的更多引用时,由垃圾回收器自动调用该方法。我画一个图解释一下,比如说我现在有一个Dog对象,它在堆内存中占了一片空间,此时d是这个对象的引用。如下图所示

 

  当我调用完Dog对象的eat方法之后,以后就再也不使用这个Dog对象了,可以将d赋值为null,那么原来那个Dog对象就没有被引用了,将来也不会再用到。此时,垃圾回收器会自动回收或者说销毁该对象,那是不是一把d赋值为null,就马上销毁该对象呢?不是的,垃圾回收器到底什么时候回收该对象,有它自己的规则,并不是说该对象没被引用了,马上回收该对象,我们也可以来进行验证一下,根据上文的描述,我们知道,当该对象被回收时,会先去调用finallize方法,默认情况下,子类的finalize方法是继承自Object父类,先来看看Object父类中的finalize方法是如何编写的,如下图所示:

根据观察可以发现,Object类的finalize方法中没有任何的代码。为了方便观察到效果,我们在Dog类中重写父类Object的finalize方法,如下图所示:

  重写完之后,我们运行程序,来验证finalize方法在此时是否会被自动调用,此时main方法中的代码是这样的,在第7行,已经将d赋值为null,意味着Dog对象已经没有任何引用了。

  运行程序,结果如下所示:观察发现,明明Dog对象已经没有被引用了,为什么finalize没有被调用呢?如我刚刚所说,虽然Dog对象没有被引用,但是垃圾回收器并不会马上回收Dog对象,它有自己的回收时机,现在只能确定该Dog对象已经可以被回收了,但是还没被回收,所以finalize方法没有被调用。

  为了看到显示的效果,我们可以编写代码,手动调用垃圾回收器让它回收该Dog对象,在main方法中,我们添加上这样一句代码,调用垃圾回收器:

  再次运行程序,观察结果:发现finalize方法果然被自动调用了,但是你再仔细观察代码发现,代码的输出是先执行第9行,然后再去调用finalize方法,也就是说System.gc调用之后,并不会阻塞在那里,等调用完finalize方法之后再执行第9行,而是一调用垃圾回收器就继续运行代码了,就先输出了第9行的代码,finalize方法反而在其后,这是允许的

  在实际的编程开发中,finalize方法一般是用来释放资源(比如数据库的连接对象文件流的对象等这些都叫资源)的,且作为程序员,我们很少在子类中去重写这个方法

   如果对于算法感兴趣,可以参考我另外一个专栏:约瑟夫环问题_小C哈哈哈的博客-CSDN博客_约瑟夫环问题

posted @ 2023-01-10 14:44  C说编程  阅读(1857)  评论(0编辑  收藏  举报