欢迎来到刘志红的博客

别人说程序员是“搬砖”的码农,但我们知道自己是追求个性的艺术家。也许我们不会过多的在意自己的外表和穿着,但在不羁的外表下,骨子里追求着代码的美、系统的美、设计的美。
扩大
缩小

对象销毁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对象的销毁
销毁父类的属性
子类对象的销毁

 

posted on 2020-11-28 11:54  MR_程序猿刘  阅读(199)  评论(0编辑  收藏  举报

导航