本文主要向大家介绍了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频道!