JAVA语言中Object的finalize()方法介绍及实例讲解
小标 2019-01-09 来源 : 阅读 1087 评论 0

摘要:本文主要向大家介绍了JAVA语言中Object的finalize()方法介绍及实例讲解,通过具体的内容向大家展示,希望对大家学习JAVA语言有所帮助。

本文主要向大家介绍了JAVA语言中Object的finalize()方法介绍及实例讲解,通过具体的内容向大家展示,希望对大家学习JAVA语言有所帮助。


finalize()是什么?


finalize()方法是Java中Object类的一个空实现方法,我们都知道,Java中所有的类都是继承自Object,那么就是说,所有的类都有这个方法。我们先来看看该方法


/**

     * Called by the garbage collector on an object when garbage collection

     * determines that there are no more references to the object.

     * A subclass overrides the {@code finalize} method to dispose of

     * system resources or to perform other cleanup.

     *

   


* The general contract of {@code finalize} is that it is invoked * if and when the Java virtual * machine has determined that there is no longer any * means by which this object can be accessed by any thread that has * not yet died, except as a result of an action taken by the * finalization of some other object or class which is ready to be * finalized. The {@code finalize} method may take any action, including * making this object available again to other threads; the usual purpose * of {@code finalize}, however, is to perform cleanup actions before * the object is irrevocably discarded. For example, the finalize method * for an object that represents an input/output connection might perform * explicit I/O transactions to break the connection before the object is * permanently discarded. *


* The {@code finalize} method of class {@code Object} performs no * special action; it simply returns normally. Subclasses of * {@code Object} may override this definition. *


* The Java programming language does not guarantee which thread will * invoke the {@code finalize} method for any given object. It is * guaranteed, however, that the thread that invokes finalize will not * be holding any user-visible synchronization locks when finalize is * invoked. If an uncaught exception is thrown by the finalize method, * the exception is ignored and finalization of that object terminates. *


* After the {@code finalize} method has been invoked for an object, no * further action is taken until the Java virtual machine has again * determined that there is no longer any means by which this object can * be accessed by any thread that has not yet died, including possible * actions by other objects or classes which are ready to be finalized, * at which point the object may be discarded. *


* The {@code finalize} method is never invoked more than once by a Java * virtual machine for any given object. *


* Any exception thrown by the {@code finalize} method causes * the finalization of this object to be halted, but is otherwise * ignored. * * @throws Throwable the {@code Exception} raised by this method * @see java.lang.ref.WeakReference * @see java.lang.ref.PhantomReference * @jls 12.6 Finalization of Class Instances */ protected void finalize() throws Throwable { }


注释里解释的大致是,当这个对象的内存不再被使用时,GC(关于GC请自行查阅资料)在收集垃圾时就会调用这个方法,看起来就像是一个对象死亡之前的回调,那么我们写下面的代码来验证下。


public class MyClass extends Object {

 

    public static void main(String[] args) {

        new MyObject();

    }

     

    static class MyObject extends Object{

        @Override

        protected void finalize() throws Throwable {

            super.finalize();

            System.out.println("finalize");

        }

    }

}

   


这里的执行结果如下图所示:



这里并没有回调这个方法,因为GC只有在内存不足时才会进行垃圾回收,如果程序还没有出现内存不足的情况就正常结束是没有垃圾回收的,所以对象不一定总会被回收,现在我们对程序做一些修改,强制进行垃圾回收。代码如下


public static void main(String[] args) {

        new MyObject();

        System.gc();

        try {

            Thread.sleep(100);

        } catch (InterruptedException e) {

            e.printStackTrace();

        }

    }

   


这里为了模拟程序运行时的GC,让程序睡眠了一段时间,不过不影响结果。可以看到,finalize()方法的确是被调用了,结果如下图:



因此,可以看出,这个方法确实是只有在GC时才会被调用,这里可以和C++的析构函数做一下对比,C++中对象的析构函数是在对象销毁过程中被调用的,所以只要创建了对象析构函数就必然会被调用。这里已经对该方法的调用时机做了验证,那么这个方法有什么用呢?


filalize()的使用场景


作为一个Java开发者,大家应该都知道,Java中所有的内存回收都是由GC来完成的,但是需要注意的是,这里指的内存使是使用Java的new关键字开辟的内存空间,如果我使用其他方式开辟的内存空间(比如C++的new关键字或者C的malloc函数)是不能被GC回收的,因此,我们应该在这个方法里释放掉非Java代码开辟的内存空间。


另外,既然finalize()作为一个GC时才调用的方法,我们可以在里面执行一些最终结果的判断,比如说,我定义了一个Student类,里面有两个属性分别是学生姓名和是否交了班费,如果没有支付班费,在对象被回收时将会记录下没有交班费的同学,代码如下所示:


static class Student{

        // 是否交班费

        private boolean isPay = false;

        // 学生姓名

        private String stdName;

        public void pay(){

            isPay = true;

        }

         

        @Override

        protected void finalize() throws Throwable {

            super.finalize();

            if(! isPay){

                System.out.println(stdName + "同学没有交班费!");

            }

        }

    }

   


当然,这只是一个例子,不一定有实际意义。


好了,以上就是我对finalize()方法的理解,如果有错误,欢迎指出。


          

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注编程语言JAVA频道!

本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程