Java 8 关于 finalize 方法的断言是否正确?

Java 8 is this assertion about finalize method correct?

我一直在读 OCA Java SE 8 程序员 I 考试指南 作者 Kathy Sierra + Bert Bates。

finalize 方法有些地方我不是很了解。它在第 218 页指出:

Calling finalize() can actually result in saving an object from deletion.

第 222 页稍后:

You can make an object ineligible for GC from within finalize().

英语不是我的母语,但我在这两种情况下的理解是 finalize() 方法可以防止对象被垃圾回收?是这样吗?还是我误解了它?

这实际上更像是一个理论问题:当对象不再被其他 活动 对象引用时,它们就有资格进行垃圾回收。

因此:您可以尝试finalize() 中创建这样的引用。理论上这会阻止对象被移除。

实际上有一个 "pattern name":object resurrection。现在,如果这是一种模式,或者更多的 anti 模式,则有待商榷。

(个人:我永远不会那样做,而且我从来没有遇到过必须使用这种模式的情况)

finalize是JVM调用的方法,用户不调用,这个方法是在对象被垃圾回收前执行的,你可以重写finalize方法在对象被释放之前或者像书中那样做清理操作说明您可以防止对象被垃圾回收。

您可以参考以下代码作为避免对象被垃圾回收的示例。

class Example { 

    static Example y; 

    void func() { 
        Example x = new Example(); 
    } 

    pubic void finalize() { 

        y = this; // Putting the reference id 
        // of the current object 
        // into the static variable y 

        System.out.println("The object won't be collected by the garbage collector"); 

    } 

    public static void main(String a[]) {
        func(); // function called 
    } 
}

嗯,确实如此。

finalize() 方法在 GC 决定应该删除对象时被调用,但这并不意味着对象将在 finalize 完成后立即被删除。

IT DOESN'T WORK THIS WAY:
_________________________
IF shouldBeRemoved(object)
   object.finalize();
   remove(object);

finalize 执行后,GC 将再次检查对象是否仍应被删除。要符合删除条件,不应从可从根对象访问的任何对象引用对象。

IT WORKS THIS WAY
_________________
LABEL
IF shouldBeRemoved(object)
    object.finalize();
    IF shouldBeRemoved(object)
        remove(object);
    ELSE
        GOTO LABEL

让我们想象一下以下情况:

class Foo {
    Application a;

    Foo(){};

    @Override
    public void finalize() {
        this.a = Application.getInstance();
    }
}

其中 Application 是一个 class,表示 Application 的根对象。在这种情况下,由于 a 仍然可达,class Foo 之前符合删除条件的对象刚刚复活。

重要说明

你不能保证 finalize 会被调用,因为它需要另一个对象来处理 finalize 方法被调用,所以如果没有足够的空闲 space 在堆上,对象可能会在不调用 finalize.

的情况下被销毁