我是一个从汽车行业转行IT的项目经理,我是Edward,如想了解更多,请关注我的公众号【转行项目经理的逆袭之路】。
finalize:Java中的一个方法名
Java使用finalize()方法在垃圾收集器将对象从内存中清除出去前,做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在Object类中定义的,因此所有的类都继承了它。子类可以重写finalize()方法以整理系统资源或者执行其他清理工作。finalize()方法是在垃圾收集器删除对象之前对这个对象调用的。
小案例如下:
/**
* finalize()
* @Title: FinalizeDemo.java
* @author: EP
* @date: 2020年5月15日上午9:34:52
*/
public class FinalizeDemo {
public static void main(String[] args) {
//创建两个Cake对象
Cake c1 = new Cake(1);
Cake c2 = new Cake(2);
//将c2标记为null,并调用gc()来清理
c2 = null;
System.gc();
}
}
class Cake extends Object{
private int id;
public Cake(int id) {
// TODO Auto-generated constructor stub
this.id=id;
System.out.println("cake: "+id+"is created");
}
//重写finalize方法
protected void finalize() {
System.out.println("cake:"+id+"is disposed");
}
}
总结:
finalize方法有如下四个特点:
1、永远不要主动调用某个对象的finalize方法,该方法应交给垃圾回收机制调用。
2、finalize方法的何时被调用,是否被调用具有不确定性。不要把finalize方法当成一定会被执行的方法。
3、当JVM执行可恢复对象的finalize方法(可恢复即没有final修饰的null)时,可能使该对象或系统中其他对象重新变成可达状态。
4、当JVM执行finalize方法时出现了异常,垃圾回收机制不会报告异常,程序继续执行。
由于finalize()方法并不一定会被执行,因此如果想清理某个类里打开的资源,则不要放在finali()方法中进行清理。
下面再补充一个finalize()复活对象的实例:
/**
* finalize()复活对象
* @Title: FinalizeTest.java
* @author: EP
* @date: 2020年5月15日上午10:05:05
*/
public class FinalizeTest {
private static FinalizeTest ft = null;
public void info() {
System.out.println("测试资源清理的finalize方法");
}
public static void main(String[] args) throws Exception {
// 创建FinalizeTest对象立即进入可恢复状态
new FinalizeTest();
// 通知系统进行资源回收
System.gc(); // A 处
// 强制垃圾回收机制调用可恢复对象的finalize()方法
// Runtime.getRuntime().runFinalization(); //B处
System.runFinalization(); // C处
ft.info();
}
public void finalize() {
// 让ft引用到试图回收的可恢复对象,即可恢复对象重新变成可达
ft = this;
}
}
A处和C处的代码必须都执行,否则因为垃圾回收的不确定性,finalize不会被执行,导致程序最终异常执行。
控制台输出成功,证明该静态对象被复活了。