18

finalize()そのオブジェクトのコンストラクターに例外があるかどうかを使用してオブジェクトがクリーンアップされるかどうかについての詳細はありますか?

このメソッドがいつ呼び出されるかは、よく定義されていません。マニュアルによると:

Java プログラミング言語は、特定のオブジェクトに対してどのスレッドが finalize メソッドを呼び出すかを保証しません。ただし、ファイナライズが呼び出されたときに、ファイナライズを呼び出すスレッドがユーザーに表示される同期ロックを保持していないことが保証されています。捕捉されなかった例外が finalize メソッドによってスローされた場合、その例外は無視され、そのオブジェクトのファイナライズは終了します。

http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#finalize%28%29

この方法で finalize メソッドをトリガーできませんでした。呼び出されないように保証されているか、コンストラクターがオブジェクトの初期化に失敗した後に呼び出される場合があるかどうか (例外があります) を知っている人はいますか?

2 回クリーンアップしてはならないオブジェクトがあるため、これをお願いします。finalize()例外をスローする前にクリーンアップしても安全かどうか、または効果的にスキップして何もしないためにマーカーを残す必要があるかどうかを理解しようとしています。

4

3 に答える 3

12

私のテストは、それができることを示しています

public class Test1 {

    Test1() {
        throw new RuntimeException();
    }

    @Override
    protected void finalize() throws Throwable {
        System.out.println("finalized");
    }

    public static void main(String[] args) throws Exception {
        try {
            new Test1();
        } catch (RuntimeException e) {
            e.printStackTrace();
        }
        System.gc();
        Thread.sleep(1000);
    }
}

版画

java.lang.RuntimeException
    at test.Test1.<init>(Test1.java:13)
    at test.Test1.main(Test1.java:24)
finalized

それはJava HostSpot Client VM 1.7.0_03上にあります

于 2013-01-23T15:42:59.397 に答える
10

セクション12.6.1によると。JLS のファイナライズの実装:

オブジェクト o は、そのコンストラクターが o の Object のコンストラクターを呼び出し、その呼び出しが正常に完了するまで (つまり、例外をスローせずに)、ファイナライズできません。

Object コンストラクターの完了後にコンストラクターが例外をスローした場合、オブジェクトはファイナライズ可能であるため、finalize()引き続き呼び出すことができます。

セクション12.5にオブジェクト構築のステップを踏む良い例があります。オブジェクト コンストラクターがいつ呼び出されるかを正確に示す新しいクラス インスタンスの作成。

于 2013-01-23T15:51:02.840 に答える
1

より明確に示すには:

public class Test1 {

    public static class LifeBoat extends RuntimeException
    {
        private Test1 passenger;
        public Test1 getPassenger(){return passenger;}
        public LifeBoat(Test1 passenger){this.passenger=passenger;}
    }

    Test1() {
        super(); //once this is finished, there is an Object to GC per JLS 12.6.1. 
        throw new LifeBoat(this);
    }

    @Override
    protected void finalize() throws Throwable {
        System.out.println("finalized");
    }

    public static void main(String[] args) throws Exception {
        try {
            new Test1();
        } catch (LifeBoat e) {
            Test1 obj;
            obj=e.getPassenger();
            System.out.println(obj);
        }
        System.gc();
        Thread.sleep(1000);
    }
}

版画

java.lang.RuntimeException
    at test.Test1.<init>(Test1.java:13)
    at test.Test1.main(Test1.java:24)
test.Test1@6dc8f3cd
finalized
于 2014-06-13T14:33:13.417 に答える