2016-07-17 2 views
2

は、私は、出力がこのgc()メソッドを使用した後、Java finalize()メソッドが呼び出されませんか?オブジェクトが破棄されようとしているとき

Number of objects :1 
Number of objects :2 
Program about to terminate 
Number of objects :1 
Program about to terminate 
Number of objects :0 
のようになることが期待

class counterTest{ 
    public static int count; 
    public counterTest(){ 
     count++; 
    } 
} 

public class finalize { 

    public static void main(String args[]){ 

     counterTest obj1=new counterTest(); 
     System.out.println("Number of objects :" + counterTest.count); 
     counterTest obj2=new counterTest(); 
     System.out.println("Number of objects :" + counterTest.count); 
     Runtime rs=Runtime.getRuntime(); 
     obj1=null; 
     obj2=null; 
     rs.gc(); 
    } 
    protected void finalize(){ 
     System.out.println("Program about to terminate"); 
     counterTest.count--; 
     System.out.println("Number of objects :" + counterTest.count); 
    } 
} 

、私が書いていると呼ばれるJavaで次のプログラムをfinalize()方法の動作を確認するには

しかし、私はちょうど最初の2行を取得しています。オブジェクトの参照をnullにしてからgc()メソッドを呼び出すため、finalize()メソッド内に記述されたステートメントを表示する必要があります。つまり、gc()メソッドを使用するたびにfinalize()メソッドが呼び出されるという保証はありませんか?

+3

gcをコールしてもファイナライズの実行が保証されるわけではありませんが、これは推奨します。 – gevorg

+2

@Sai [java code convention](http://www.oracle.com/technetwork/java/codeconventions-150003.pdf)を参照してください。 –

+0

[Javaでガベージコレクションを強制する方法?](http://stackoverflow.com/questions/1481178/how-to-force-garbage-collection-in-java) – gevorg

答えて

2

finalizeメソッドはcounterTestにある必要があります。そして、それは "多分"呼び出されます。あなたは決して本当に "finalize"クラスのインスタンスとインスタンスを作成しません。したがって、finalizeメソッドは実行されることはありません。

はここにあなたが期待するよう動作するはずのコードを更新されます

class counterTest{ 
    public static int count; 
    public counterTest(){ 
     count++; 
    } 

    protected void finalize(){ 
     System.out.println("Program about to terminate"); 
     counterTest.count--; 
     System.out.println("Number of objects :" + counterTest.count); 
    } 
} 

public class Finalize { 

    public static void main(String args[]){ 

     counterTest obj1=new counterTest(); 
     System.out.println("Number of objects :" + counterTest.count); 
     counterTest obj2=new counterTest(); 
     System.out.println("Number of objects :" + counterTest.count); 
     Runtime rs=Runtime.getRuntime(); 
     obj1=null; 
     obj2=null; 
     rs.gc(); 
    } 

} 

彼らが信頼できないので、「確定」メソッドをオーバーライドすることを意味しないことに留意すべきです。ガベージコレクタが特定のオブジェクトを収集してデータベース接続を閉じたり、他の同様の処理を行うためにリレーするときは、いいえ、いいえ、いいえはわかりません。

+0

ありがとうございました。なぜfinalize()メソッドは、 10個のクラスがある場合、各クラスに10個のfinalize()メソッドが必要ですか? –

+1

* *呼び出すことができます。ファイナライズだけでなく、GCが呼び出されることを保証するものは何もありません。 – EJP

+1

@SaiSankalpそれは意味をなさない。クラスごとに1つの* finalize()メソッド。 – EJP

2

まず、コードにはインスタンス(AKAオブジェクト)はfinalizeクラスです。 mainメソッドは静的であり、インスタンスを持ちません。

インスタンスを持っていても、Java GCではfinalize()メソッドを呼び出すことはあまり決定的ではなく、保証されません。これはC++に似たデストラクタではありません。したがって、counterTestクラスにfinalize()メソッドを追加した場合でも、インスタンスをいくつか作成すると、それが呼び出される保証はありません。

デストラクタと同様の動作が必要な場合は、try-with-resourcesパターンの周りにコードを設計する必要があります。その後、AutoCloseable interface's close() methodがデストラクタの役割を担います。

PS。 非常にのJavaで強力な規約があり、クラス名でPascalと呼ばれるケースを使用するため、クラス名はCounterTestFinalizeとする必要があります。

関連する問題