與C++不同,Java有自己的記憶體回收機制,同時,Java沒有了解構函式的概念,轉而提供了一個finalize方法,那麼finalize方法會在什麼時間執行呢?
或許有人以為是在將引用設定為null的時候,現在先看下面的例子:
public class Test {<br />public static void main(String[] args) {<br />// TODO Auto-generated method stub<br />Demo d = new Demo();<br />System.out.println("begin to set d to null");<br />d = null;<br />System.out.println("d was set to null");<br />}<br />}</p><p>class Demo {<br />@Override<br />protected void finalize() throws Throwable {<br />// TODO Auto-generated method stub<br />System.out.println("Demo finalized");<br />super.finalize();<br />}<br />}
運行一下代碼,結果如下:
begin to set d to null<br />d was set to null
finalize方法根本沒有被執行,看一下java中對finalize方法的定義:Called by the garbage collector on an object when garbage collection determines that there are no more references to the object. 當記憶體回收確認沒有指向對象的引用時,執行回收。而上面的代碼建立的對象Demo的唯一引用d已經被釋放,而確有執行Demo類的finalize方法,唯一的原因只能是gc並沒有執行,gc只有在JVM記憶體不足的時候才會自動執行,為了測試,我們將代碼作一下修改:
public class Test {<br />public static void main(String[] args) {<br />// TODO Auto-generated method stub<br />Demo d = new Demo();<br />System.out.println("begin to set d to null");<br />d = null;<br />System.out.println("d was set to null");<br />System.out.println("begin run gc");<br />System.gc();<br />System.out.println("gc runed");<br />}<br />}</p><p>class Demo {<br />@Override<br />protected void finalize() throws Throwable {<br />// TODO Auto-generated method stub<br />System.out.println("Demo finalized");<br />super.finalize();<br />}<br />}
運行結果如下:
begin to set d to null<br />d was set to null<br />begin run gc<br />gc runed<br />Demo finalized
所以finalize方法只有在JVM執行gc時才會被執行,所以我們在寫代碼用到的時候需注意,這裡面的代碼不知道什麼時候才會去執行,所以要盡量少用。
下一篇: Java牛角尖【006】: 匿名內部類可以繼承其它類嗎?