zoukankan      html  css  js  c++  java
  • 《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;
    

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

  • 相关阅读:
    解决 搭建Jekins过程中 启动Tomcat的java.net.UnknownHostException异常
    射手和农场主
    java 和 JS(javaScript)中的反斜杠正则转义
    分享修改密码的SharePoint Web part: ITaCS Change Password web part
    分享微软官方Demo用的SharePoint 2010, Exchange 2010, Lync 2010虚拟机
    Office 365 的公共网站的一些限制及解决的办法
    SharePoint 2013 关闭 customErrors
    安装 KB2844286 导致SharePoint 2010 XSLT web part 显示出现错误
    安装Office Web Apps Server 2013 – KB2592525安装失败
    如何将hyper-v虚拟机转换成vmware的虚拟机- 转换SharePoint 2010 Information Worker Demonstration and Evaluation Virtual Machine (SP1)
  • 原文地址:https://www.cnblogs.com/mrbourne/p/8797417.html
Copyright © 2011-2022 走看看