zoukankan      html  css  js  c++  java
  • 对象销毁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对象的销毁
    销毁父类的属性
    子类对象的销毁
  • 相关阅读:
    Web前端一种动态样式语言-- Less
    Windows下查看8080进程及结束进程命令
    Java应用程序实现屏幕的"拍照"
    批处理命令 BAT备份MySQL数据库
    LineNumberReader类
    SAXReader
    linux打包压缩命令汇总
    Jquery获取选中的checkbox的值
    Jquery_联系电话正则表达式
    CSS overflow 属性
  • 原文地址:https://www.cnblogs.com/chengxuyuan-liu/p/14052088.html
Copyright © 2011-2022 走看看