以下是Java中finalize()方法的详细讲解:
finalize()方法是什么?
finalize()方法是Object类中定义的一个方法,用于在对象被垃圾回收器回收时调用。子类可以覆盖此方法以在对象变为不可达时执行任意清理操作,例如,关闭已打开的文件或套接字。
finalize()方法的执行时机
Java垃圾回收器会定期检查堆上的对象,并确定哪些对象是不再被引用的,以便释放它们占用的内存。 在垃圾回收过程中,当确定对象不再被引用时,将调用finalize()方法。 确切的时间是由垃圾回收器的实现决定的,因此执行finalize()方法的时间是不确定的。
以下是一个重写了finalize()方法的示例代码:
public class MyClass {
private SomeResource resource;
// 构造函数
public MyClass() {
resource = new SomeResource();
}
// 重写finalize()方法
@Override
protected void finalize() throws Throwable {
try {
resource.close();
} finally {
super.finalize();
}
}
}
在这个示例代码中,MyClass类包含一个资源对象resource,并且在构造函数中对其进行初始化。我们重写了finalize()方法,以确保在MyClass对象被垃圾回收器回收之前,会关闭resource对象。
注意事项
finalize()方法不应该用于释放内存
虽然可以在finalize()方法中关闭文件和套接字等资源,但是它不是释放内存的可靠方式。因为垃圾回收机制本身就是用于释放内存的,如果Java虚拟机未执行finalize方法,那么系统里就会有未关闭的文件和套接字。因此,finalize()方法应当被视为一个通知机制,告诉程序应当执行一些清理动作。
finalize()方法只会被执行一次
在Java中,当一个对象被标记为“不可达”时,垃圾回收器只会对其调用一次finalize()方法。之后,对象就会被视为死亡对象,之后就不会再次执行finalize()方法。因此,如果需要在多次对象回收前做一些清理动作,应当显式调用相关方法,而不是依靠finalize()方法。
示例代码
以下是一个Person类的示例代码,实现了finalize()方法:
public class Person {
private String name;
private int age;
// 构造函数
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// 重写finalize()方法
@Override
protected void finalize() throws Throwable {
try {
System.out.println(name + "对象被回收了");
} finally {
super.finalize();
}
}
// 主函数
public static void main(String[] args) {
Person p1 = new Person("张三", 20);
p1 = null;
Person p2 = new Person("李四", 30);
p2 = null;
// 强制垃圾回收
System.gc();
}
}
在这个示例代码中,我们创建了两个Person对象,并将其设置为null。接着,我们强制执行垃圾回收(System.gc()方法),此时,会自动执行Person对象的finalize()方法。
输出结果如下:
张三对象被回收了
李四对象被回收了
可以看到,当Person对象被垃圾回收器回收时,会自动调用finalize()方法,输出一条提示信息。