首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 ><Thinking in java,4 Edition>中的finalize方法

<Thinking in java,4 Edition>中的finalize方法
EN

Stack Overflow用户
提问于 2014-09-14 06:11:59
回答 3查看 217关注 0票数 3

我在读Java的思考,第四版。我发现了一个问题:当我在Eclipse中测试源代码时,我发现结果是不同的。我希望有人能帮我!

这里是源代码

代码语言:javascript
复制
class Book {
    boolean checkedOut = false;

    Book(boolean checkOut) {
        checkedOut = checkOut;
    }

    void checkIn() {
        checkedOut = false;
    }

    protected void finalize() {
        if(checkedOut)
            System.out.println("Error:checked out");  
            //Normally,you'll also do this:
            //super.finalize();//Call the base-class version
    }
}


public class TerminationCondition {
    public static void main(String[]args) {
        Book novel=new Book(true);

        //Proper cleanup:
        novel.checkIn();

        //Drop the reference,forget to clean up:
        new Book(true);
        new Book(true);
        new Book(true);

        //Force garbage collection & finalization:
        System.gc();
    }
}

图书的结果:

代码语言:javascript
复制
Error: Checked out

IDE的结果

代码语言:javascript
复制
(nothing)

我使用的Java版本:

Java版本"1.7.0_51“

Java(TM) SE运行时环境(build 1.7.0_51-b13)

Java HotSpot(TM) 64位服务器VM (build 24.51-b03,混合模式)

本书中Java的版本是Java 5,对finalize方法做了一些更改吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-09-14 06:16:15

在运行GC之前,您的主线程已经退出。所以你没有得到任何输出。在主方法中执行以下更改,您将看到输出:-

代码语言:javascript
复制
System.gc();
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
票数 0
EN

Stack Overflow用户

发布于 2014-09-14 06:16:03

JVM有自己的垃圾收集管理策略,即使您单独或不调用finalize()!JVM做得非常好,用户不需要在垃圾内存清理过程中进行干预。

所以,您所观察到的与Java版本或任何事情无关!它完全依赖于JVM和自动内存管理策略。

票数 1
EN

Stack Overflow用户

发布于 2014-09-14 06:50:02

本书中Java的版本是Java 5,对finalize方法做了一些更改吗?

如果您阅读了System.gc()和相关内容的规范,您将看到几乎没有什么保证会发生什么:

  1. 不能保证调用System.gc()会导致任何事情发生。我是认真的。
  2. 不能保证所有的垃圾都会被收集。
  3. 不能保证垃圾对象最终确定.无法抵挡finalize()方法。

这里真正的问题是,你看到的例子是做出毫无根据的假设。它恰好适用于较早版本的Java。它不适用于最近的.或者类似的东西。这只是一个坏的例子。

但这确实(我希望)向您证明,依赖于在可预测的时间调用finalize方法是不明智的。实际上,最好不要在任何事情上使用finalize .除了“皮带和支撑”清理代码。

实际上,终结通常是在垃圾收集器完成之后进行的。(这是由一个守护进程“终结线程”完成的,它可以处理所有已被识别为不可到达的对象,并且需要完成。)因此,在您的示例中可能发生的情况是,JVM在运行GG之后退出,但在终结线程获得处理可终结对象的机会之前。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25830592

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档