我需要知道什么时候在JVM中调用finalize()方法。我创建了一个测试类,当finalize()方法被重写时写入文件。它没有被执行。有人能告诉我为什么它不能执行吗?


当前回答

Java allows objects to implement a method called finalize() that might get called. finalize() method gets called if the garbage collector tries to collect the object. If the garbage collector doesn't run, the method doesn't get called. If the garbage collector fails to collect the object and tries to run it again, the method doesn't get called in the second time. In practice, you are highly unlikely to use it in real projects. Just keep in mind that it might not get called and that it definitely won't be called twice. The finalize() method could run zero or one time. In the following code, finalize() method produces no output when we run it since the program exits before there is any need to run the garbage collector.

其他回答

protected void finalize() throws Throwable {} every class inherits the finalize() method from java.lang.Object the method is called by the garbage collector when it determines no more references to the object exist the Object finalize method performs no actions but it may be overridden by any class normally it should be overridden to clean-up non-Java resources ie closing a file if overridding finalize() it is good programming practice to use a try-catch-finally statement and to always call super.finalize(). This is a safety measure to ensure you do not inadvertently miss closing a resource used by the objects calling class protected void finalize() throws Throwable { try { close(); // close open files } finally { super.finalize(); } } any exception thrown by finalize() during garbage collection halts the finalization but is otherwise ignored finalize() is never run more than once on any object

引用自:http://www.janeg.ca/scjp/gc/finalize.html

你也可以看看这篇文章:

对象终结和清理

Finalize将打印出类创建的计数。

protected void finalize() throws Throwable {
    System.out.println("Run F" );
    if ( checkedOut)
        System.out.println("Error: Checked out");
        System.out.println("Class Create Count: " + classCreate);
}

main

while ( true) {
    Book novel=new Book(true);
    //System.out.println(novel.checkedOut);
    //Runtime.getRuntime().runFinalization();
    novel.checkIn();
    new Book(true);
    //System.runFinalization();
    System.gc();

如你所见。下面的输出显示了类计数为36时第一次执行的gc。

C:\javaCode\firstClass>java TerminationCondition
Run F
Error: Checked out
Class Create Count: 36
Run F
Error: Checked out
Class Create Count: 48
Run F

Finalize()在垃圾收集之前被调用。当对象超出作用域时,不调用它。这意味着您无法知道finalize()何时甚至是否会执行。

例子:

如果你的程序在垃圾回收发生之前结束,finalize()将不会执行。因此,它应该被用作备份过程,以确保其他资源的正确处理,或用于特殊用途的应用程序,而不是作为您的程序在其正常运行中使用的手段。

查看Effective Java,第2版第27页。 第7项:避免终结词

终结器是不可预测的,通常是危险的,而且通常是不必要的。永远不要在终结器中做任何时间紧迫的事情。从来没有 依赖终结器更新关键持久状态。

要终止一个资源,请使用try-finally:

// try-finally块保证终止方法的执行 Foo Foo =新的Foo(…); 尝试{ //用foo做必须做的事情 ... }最后{ foo.terminate ();//显式终止方法 }

类,在其中重写finalize方法

public class TestClass {    
    public TestClass() {
        System.out.println("constructor");
    }

    public void display() {
        System.out.println("display");
    }
    @Override
    public void finalize() {
        System.out.println("destructor");
    }
}

finalize方法被调用的几率

public class TestGarbageCollection {
    public static void main(String[] args) {
        while (true) {
            TestClass s = new TestClass();
            s.display();
            System.gc();
        }
    }
}

当内存被转储对象重载时,gc将调用finalize方法

运行并查看控制台,在那里你不会发现finalize方法被频繁调用,当内存超载时,finalize方法将被调用。