引言

java中一切对象的创建都在堆,由gc自动回收。而局部变量的存储都在堆栈上会随着方法的运行结束弹栈而销毁。那Object提供的finalize有什么用呢?

finalize的用处

java有一种可以调用本地其他语言的方法native,例如调用C++,而C++程序对象的销毁必须手动的调用析构函数进行销毁。如果我们当前调用了这个本地方法创建了C++对象,那么就必须对这个C++对象进行销毁,这就使finalize有了用武之地。

而finalize方法不是总是执行的,而是在gc准备释放对象占用的存储空间,将首先调用其finilize方法。(误区:调用finilize方法对该对象占用的内存进行释放)

finalize不是一定执行

由于垃圾回收也有开销,所以程序没有濒临存储空间用完的那一刻,对象占用的空间就总也得不到释放。如果执行程序结束并且垃圾回收器一直没有释放你创建的任何对象的存储空间,则随着程序的退出,这些占用的资源也还给了操作系统。

模拟对象销毁

1. 独立对象的销毁

//要被组合的对象
public classOtherObj{publicOtherObj() {
System.out.println("Other对象的创建");
}/*** 对象销毁*/
public voiddispose(){
System.out.println("Other对象的销毁");
}
}//父类
public classParent {publicParent() {
System.out.println("父类构造的调用");
}public voiddispose(){
System.out.println("父类中销毁方法的调用,用来销毁父类中的属性");
}
}//子类
public class Sub extendsParent {private OtherObj otherObj = newOtherObj();publicSub() {
System.out.println("子类对象的创建");
}
@Overridepublic voiddispose() {this.otherObj.dispose();//System.out.println(super); 编译报错,根本就不存在super对象只是可以调用父类的方法(子类调用)
super.dispose();
System.out.println("子类对象的销毁");
}public static voidmain(String[] args) {
Sub sub= newSub();
sub.dispose();

}//运行结果

父类构造的调用

Other对象的创建

子类对象的创建

Other对象的销毁

父类中销毁方法的调用,用来销毁父类中的属性

子类对象的销毁

2. 共享对象的销毁,通过引用计数来跟踪共享对象的数量

public classOtherObj {private static int counter = 0;private final int id = counter++;/*** 一个对象被引用的次数*/
private int refCount = 0;publicOtherObj() {
System.out.println("Other对象的创建");
}/*** 对象销毁*/
public voiddispose(){if (--refCount==0){
System.out.println("Other对象的销毁");
}
}/***
*@return
*/
public intaddRef() {return refCount++;
}
@OverridepublicString toString() {return "OtherObj的对象,id=" +id;
}
}//父类
packagetop.liuzhihong.polymorphic.c;/***@authorProgrammer_Liu.
*@since2020-11-28 11:10*/
public classParent {publicParent() {
System.out.println("父类构造的调用");
}public voiddispose(){
System.out.println("销毁父类的属性");
}
}//子类
public class Sub extendsParent {privateOtherObj otherObj;publicSub(OtherObj otherObj) {
System.out.println("子类对象的创建");this.otherObj =otherObj;this.otherObj.addRef();
}
@Overridepublic voiddispose() {this.otherObj.dispose();//System.out.println(super); 编译报错,根本就不存在super对象只是可以调用父类的方法(子类调用)
super.dispose();
System.out.println("子类对象的销毁");
}public static voidmain(String[] args) {
OtherObj otherObj= newOtherObj();
Sub[] subs= newSub[]{newSub(otherObj),newSub(otherObj),newSub(otherObj),
};for(Sub sub : subs) {
sub.dispose();
}
}

}//运行结果

Other对象的创建

父类构造的调用

子类对象的创建

父类构造的调用

子类对象的创建

父类构造的调用

子类对象的创建

销毁父类的属性

子类对象的销毁

销毁父类的属性

子类对象的销毁

Other对象的销毁

销毁父类的属性

子类对象的销毁