質問
私はURLClassLoader
匿名のクラスを持っています。その中で、メソッドをオーバーライドして、finalize()
ガベージ コレクション時にオブジェクトが自動的に閉じられるようにしました。
protected void finalize() throws Throwable {
close();
}
メソッドをオーバーライドして、close()
いくつかの情報を出力しました。
public void close() throws IOException {
System.out.println("Closing...");
super.close();
System.out.println("Closed.");
}
このオブジェクトを作成した直後に、System.gc()
それを破棄するために呼び出します。予想どおり、finalize()
メソッドが呼び出され、次にメソッドが呼び出されますが、コンソールに出力されるclose()
だけです。Closing...
実行が 2 番目の print ステートメントに到達しないのはなぜですか?
ノート
私が最初に疑ったのは、それsuper.close()
が例外をスローしていたことであり、ガベージ コレクション用にオブジェクトを準備するものは何でも例外を飲み込んでいたので、いずれかをキャッチして出力しようThrowable
としました。
public void close() throws IOException {
System.out.println("Closing...");
try {
super.close();
System.out.println("Closed.");
} catch (Throwable e) {
e.printStackTrace();
}
}
しかし、以前とまったく同じ出力が得られました: Closing...
. 次に、クラス ローダーを手動で閉じた場合にどうなるかをテストしたので.close()
、System.gc(); を実行する代わりに、作成直後にクラス ローダーを呼び出しました。この場合、両方の印刷ステートメントが実行されました。
Closing...
Closed.