1. 程式人生 > >java之finalize在繼承關係中的使用

java之finalize在繼承關係中的使用

轉載請註明出處

http://blog.csdn.net/pony_maggie/article/details/44524077

作者:小馬


假設在基類BaseA中過載了finalize,如果繼承類DerivedA中也要過載finalize,一定要先呼叫基類的版本,否則基類的finalize不會自動呼叫。



看一個程式碼示例:

class DoBaseFinalization
{
	public static boolean flag = false;
}

class Characteristic
{
	String s;
	Characteristic(String c)
	{
		s = c;
		System.out.println("Creating characteritic " + s);
	}
	
	protected void finalize()
	{
		System.out.println("finalizing characteristic " + s);
	}
}

class LivingCreature
{
	Characteristic p = new Characteristic("is alive");
	LivingCreature()
	{
		System.out.println("LivingCreature()");
	}
	protected void finalize() throws Throwable
	{
		System.out.println("LivingCreature finalizing");
		if(DoBaseFinalization.flag) super.finalize();
	}
	
	
}

class Animal extends LivingCreature
{
	Characteristic p = new Characteristic("has heart");
	Animal()
	{
		System.out.println("Animal()");
	}
	protected void finalize() throws Throwable
	{
		System.out.println("Animal finalizing");
		if(DoBaseFinalization.flag) super.finalize();
	}
}
class Amphibian extends Animal
{
	Characteristic p = new Characteristic("can live in water");
	Amphibian()
	{
		System.out.println("Amphibian()");
	}
	protected void finalize() throws Throwable
	{
		System.out.println("Amphibian finalizing");
		if(DoBaseFinalization.flag) super.finalize();
	}
}


public class Frog extends Amphibian
{
	Frog()
	{
		System.out.println("Frog()");
	}
	protected void finalize() throws Throwable
	{
		System.out.println("Frog finalizing");
		if(DoBaseFinalization.flag) super.finalize();
	}
	/**
	 * @param args
	 */
	public static void main(String[] args) 
	{
		if((args.length != 0) && (args[0].equals("finalize")))
		{
			DoBaseFinalization.flag = true;
		}
		else System.out.println("not finalizing bases");
		
		new Frog();
		System.out.println("Bye");
		System.gc();

	}

}

不加引數直接執行的結果是
not finalizing bases
Creating characteritic is alive
LivingCreature()
Creating characteritic has heart
Animal()
Creating characteritic can live in water
Amphibian()
Frog()
Bye
finalizing characteristic can live in water
finalizing characteristic has heart
finalizing characteristic is alive
Frog finalizing
</pre>加上finalize引數之後的執行結果<p></p><p></p><pre code_snippet_id="624937" snippet_file_name="blog_20150321_4_804209" name="code" class="html">Creating characteritic is alive
LivingCreature()
Creating characteritic has heart
Animal()
Creating characteritic can live in water
Amphibian()
Frog()
Bye
finalizing characteristic can live in water
finalizing characteristic has heart
finalizing characteristic is alive
Frog finalizing
Amphibian finalizing
Animal finalizing
LivingCreature finalizing


finalize引數控制一個標誌位,決定是否呼叫基類的finalize
protected void finalize() throws Throwable
	{
		System.out.println("Frog finalizing");
		if(DoBaseFinalization.flag) super.finalize();
	}



從執行結果上也證明了開篇講到的結論。再補充一個知識點,注意到main函式中建立Frog例項的方法:
new Frog();
System.out.println("Bye");
System.gc();

如下改成這樣:
Frog a = new Frog();
System.out.println("Bye");
System.gc();

執行發現所有的類都不會呼叫finalize了。這是因為new Frog分配了例項空間後沒有被任何變數引用,呼叫完System.gc後,虛擬機器檢查到一個未引用的空間就會開始釋放流程。