finalize()是什么?
finalize()方法是Java中Object类的一个空实现方法,我们都知道,Java中所有的类都是继承自Object,那么就是说,所有的类都有这个方法。我们先来看看该方法
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()方法的理解,如果有错误,欢迎指出。
转载自:https://blog.csdn.net/cai18381306175/article/details/79890346