对象销毁finalize的理解
引言
java中一切对象的创建都在堆,由gc自动回收。而局部变量的存储都在堆栈上会随着方法的运行结束弹栈而销毁。那Object提供的finalize有什么用呢?
finalize的用处
java有一种可以调用本地其他语言的方法native,例如调用C++,而C++程序对象的销毁必须手动的调用析构函数进行销毁。如果我们当前调用了这个本地方法创建了C++对象,那么就必须对这个C++对象进行销毁,这就使finalize有了用武之地。
而finalize方法不是总是执行的,而是在gc准备释放对象占用的存储空间,将首先调用其finilize方法。(误区:调用finilize方法对该对象占用的内存进行释放)
finalize不是一定执行
由于垃圾回收也有开销,所以程序没有濒临存储空间用完的那一刻,对象占用的空间就总也得不到释放。如果执行程序结束并且垃圾回收器一直没有释放你创建的任何对象的存储空间,则随着程序的退出,这些占用的资源也还给了操作系统。
模拟对象销毁
1. 独立对象的销毁
//要被组合的对象 public class OtherObj{ public OtherObj() { System.out.println("Other对象的创建"); } /** * 对象销毁 */ public void dispose(){ System.out.println("Other对象的销毁"); } } //父类 public class Parent { public Parent() { System.out.println("父类构造的调用"); } public void dispose(){ System.out.println("父类中销毁方法的调用,用来销毁父类中的属性"); } } //子类 public class Sub extends Parent { private OtherObj otherObj = new OtherObj(); public Sub() { System.out.println("子类对象的创建"); } @Override public void dispose() { this.otherObj.dispose(); //System.out.println(super); 编译报错,根本就不存在super对象只是可以调用父类的方法(子类调用) super.dispose(); System.out.println("子类对象的销毁"); } public static void main(String[] args) { Sub sub = new Sub(); sub.dispose(); } //运行结果 父类构造的调用 Other对象的创建 子类对象的创建 Other对象的销毁 父类中销毁方法的调用,用来销毁父类中的属性 子类对象的销毁
2. 共享对象的销毁,通过引用计数来跟踪共享对象的数量
public class OtherObj { private static int counter = 0; private final int id = counter++; /** * 一个对象被引用的次数 */ private int refCount = 0; public OtherObj() { System.out.println("Other对象的创建"); } /** * 对象销毁 */ public void dispose(){ if (--refCount==0){ System.out.println("Other对象的销毁"); } } /** * * @return */ public int addRef() { return refCount++; } @Override public String toString() { return "OtherObj的对象,id=" + id; } } //父类 package top.liuzhihong.polymorphic.c; /** * @author Programmer_Liu. * @since 2020-11-28 11:10 */ public class Parent { public Parent() { System.out.println("父类构造的调用"); } public void dispose(){ System.out.println("销毁父类的属性"); } } //子类 public class Sub extends Parent { private OtherObj otherObj; public Sub(OtherObj otherObj) { System.out.println("子类对象的创建"); this.otherObj = otherObj; this.otherObj.addRef(); } @Override public void dispose() { this.otherObj.dispose(); //System.out.println(super); 编译报错,根本就不存在super对象只是可以调用父类的方法(子类调用) super.dispose(); System.out.println("子类对象的销毁"); } public static void main(String[] args) { OtherObj otherObj = new OtherObj(); Sub[] subs = new Sub[]{ new Sub(otherObj), new Sub(otherObj), new Sub(otherObj), }; for (Sub sub : subs) { sub.dispose(); } } } //运行结果 Other对象的创建 父类构造的调用 子类对象的创建 父类构造的调用 子类对象的创建 父类构造的调用 子类对象的创建 销毁父类的属性 子类对象的销毁 销毁父类的属性 子类对象的销毁 Other对象的销毁 销毁父类的属性 子类对象的销毁
作者:刘志红
-------------------------------------------
个性签名:独学而无友,则孤陋而寡闻。做一个灵魂有趣的人!
如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,博主在此感谢!