0

私が次のクラスを持っていると仮定します

   class A {
           //some attributes 

        @override
         protected void finalize() throws Throwable {
              //do something

       }
  }


   class B extends A {

           @override
         protected void finalize() throws Throwable {
             //DONT call super.finalize() 
             //do something

       }
     }

このシナリオではどうなりますか?クラスAのfinalizeメソッドを呼び出すと、ある時点でガベージコレクターによって呼び出されますか?

とにかくガベージコレクターによって呼び出される場合、それを呼び出すことと、子クラスのfinalizeメソッドでAのfinalizeメソッドを呼び出さないことの違いは何ですか?

どのシナリオで、子クラスで親のfinalizeメソッドを呼び出さなくても大丈夫ですか?そのようなシナリオの例はありますか?

4

4 に答える 4

2

まず、finalize() メソッドを明示的に呼び出すことは、他の Java メソッドを呼び出すことと同じです。特定のクラスがメソッドをオーバーライドしている場合、親の finalize() メソッドを呼び出さないことは決してfinalize()OK ではありません。もちろん、ファイナライザー ガーディアン パターンを実装する場合は、サブクラスで親ファイナライザーを明示的に呼び出す必要はありません。

finalize()ところで、ファイナライザーは非決定論的であるため、明示的にクリアできるリソースをクリーンアップする方法(ファイルハンドルを閉じるなど)に依存しないでください。また、ファイナライザーの代わりに Phantom 参照を使用することについてのBob Lee によるプレゼンテーションもご覧ください。

于 2011-07-29T12:11:25.870 に答える
2

super.finalize()リソースのリークを防ぐために、常に呼び出す必要があります。これこれを参照してください。ガベージ コレクターは常にfinalize()多くても 1 回呼び出しますが、ポリモーフィズムにより、オーバーライドされたメソッドのみが明示的に呼び出されます。

finalize()内部finallyで呼び出して、確実に呼び出されるようにすることをお勧めします。しかし、私はあなたにもっと良いアドバイスをします: 全く依存しないでくださいfinalize. リソースをできるだけ早く明示的に閉じて、新しい Java 7 機能を試してください: try with resource

于 2011-07-29T12:17:17.740 に答える
1

いいえ、他のメソッド呼び出しのようBに明示的に使用しない場合は、'finalizeメソッドのみが呼び出されます。super.finalize()

ただし、スーパークラスのfinalizeメソッドを呼び出さないのは良い習慣ではないことに注意してください。リソースなどを誤って閉じるのを見逃す可能性があります。

于 2011-07-29T12:13:31.450 に答える
1

あなたの質問に答えるために、

  1. ガベージ コレクターはある時点で finalize() メソッドを呼び出しますが、それは保証されていません。

  2. ガベージ コレクションは、現在のオブジェクトに対してのみ finalize() を呼び出します。したがって、B で finalize() を呼び出しても、super.finalize() を使用して明示的に呼び出されない限り、A で finalize() は呼び出されません。

  3. オブジェクトがガベージ コレクションされる前にクリーンアップ操作を実行する場合は、 finalize() メソッドが呼び出されます。A と B の finalize メソッドの実装が異なり、B のファイナライズが As に依存しない場合は、親の finalize メソッドを呼び出すべきではありません。たとえば、A の finalize() メソッドは特定のリソースを解放し、特殊化されたクラス B も特定のリソースを解放します (As とは無関係)。同様に、A のリソースを使用している A の他のサブクラスが存在する可能性があります (したがって、A の finalize() をオーバーライドしません)。この場合、B.finalize から super.finalize() を呼び出すと、A が保持するリソースが他のサブクラスによって使用されるため、問題が発生する可能性があります。

于 2011-07-29T12:21:13.743 に答える