• 《TIJ4》初始化与清理 练习 E10-E12 练习使用finalize()


    练习10:编写一个具有finalize()方法的类,并在方法中打印消息,在main()方法中为该类创建一个对象。

    package initialization;
    
    public class E10_FinalizeCall {
    
        protected void finalize(){
            System.out.println("finalize() called");
        }
    
        public static void main(String[] args) {
            new E10_FinalizeCall();
    }
    

    注意这里并没有声明对象的引用,只有这样,垃圾回收时才会回收这个对象。
    该程序中的终结器不一定会被调用,因为程序通常并没有产生足够的垃圾供回收器回收。

    练习11:修改上面的程序,使得finalize()方法总会被调用。

    package initialization;
    
    public class E10_FinalizeCall {
    
        protected void finalize(){
            System.out.println("finalize() called");
        }
    
        public static void main(String[] args) {
            new E10_FinalizeCall();
            System.gc();
            System.runFinalization();   
        }
    }
    

    这里增加了两行代码:

    System.gc();
    System.runFinalization();
    

    依次调用这两个方法会建议系统垃圾回收从而调用finalize(),但这不一定会发生。 调用这两个方法只会请求垃圾回收,它不能终结器一定会执行。
    因此,无法保证finalize()方法总被调用。

    练习12:编写Tank类,此类的状态可以是“满的”或“空的”, 其终结条件是:对象被清理时,必须处于空状态。编写finalize()以校验终结条件是否成立。在main()中测试Tank的几种使用方式。

    package initialization;
    
    public class Tank {
    
        static long counter;
        long id = counter++;
        boolean full;
    
        public Tank() {
            System.out.println(this + " created");
            full = true;
        }
    
        public void empty(){
            full = false;
        }
    
        protected void finalize(){
            if(full)
                System.out.println("Error: " + this + " must be empty at cleanup");
            else
                System.out.println(this + " cleaned up OK");
        }
    
        @Override
        public String toString() {
            return "Tank " + id;
        }
    
        public static void main(String[] args) {
            // 正确的使用和清理
            new Tank().empty();
            // 状态不为空时的清理
            new Tank();
            // 请求垃圾回收
            System.gc();
            System.runFinalization();
        }
    }
    
    

    这里我们创建了两个没有引用的Tank实例,因为如果我们创建了引用,那么在调用System.gc()时这些引用仍在作用域中,因此它们就不会被清理,终结器finalize()也就不会被调用。另一种方法是将引用置为null,这样也可以使引用原来指向的对象被回收。例如:

    Tank tank = new Tank();
    tank = null;
    

    你永远也无法保证终结器一定会被调用,因此它们的功能就很受限。这里终结器可以用来在垃圾回收时,检测对象的状态,以确保对象可以正确得被清理。

  • 相关阅读:
    Docker中查看Mysql数据库中的各环境参数
    Hbase shell 输入无法使用退格键删除解决办法
    HBase启动时报错:/bin/java: No such file or directory6/bin/../bin/hbase: line 412: /usr/local/jdk1.8.0_152/bin/java
    SSH无密码验证
    详解分布式应用程序协调服务Zookeeper
    zookeeper的原理及使用
    Hadoop、Yarn和vcpu资源的配置
    一文让您全面了解清楚HBase数据库的所有知识点,值得收藏!
    基于Docker一键部署大规模Hadoop集群及设计思路
    PHP ServerPush (推送) 技术的探讨【转】
  • 原文地址:https://www.cnblogs.com/mrbourne/p/8797417.html
Copyright © 2020-2023  润新知