1. 程式人生 > >高頻面試題:final,finally,finalize的區別

高頻面試題:final,finally,finalize的區別

-final Final可以用於成員變數(包括方法引數),方法、類。 Final成員 作為變數 變數一旦被初始化便不可改變(對於基本型別,指的是值不變;對於物件型別,指的是引用不變),初始化只可能在兩個地方:定義處和建構函式。 作為方法引數 對於基本型別,定義成final引數沒有什麼意義,因為基本型別就是傳值,不會影響呼叫語句中的變數; 對於物件型別,在方法中如果引數確認不需要改變時,定義成final引數可以防止方法中無意的修改而影響到呼叫方法。 Final方法 不可覆寫 編譯器將對此方法的呼叫轉化成行內(inline)呼叫,即直接把方法主體插入到呼叫處(方法主體內容過多的時候反而會影響效率) Final類 不可繼承 -------------------------------------------------------------------------------------------------------------------finalize

類的Finalize方法,可以告訴垃圾回收器應該執行的操作,該方法從Object類繼承而來。 在從堆中永久刪除物件之前,垃圾回收器呼叫該物件的Finalize方法。 注意,無法確切地保證垃圾回收器何時呼叫該方法,也無法保證呼叫不同物件的方法的順序。 即使一個物件包含另一個物件的引用,或者在釋放一個物件很久以前就釋放了另一個物件, 也可能會以任意的順序呼叫這兩個物件的Finalize方法。如果必須保證採用特定的順序,則必須提供自己的特有清理方法。

-------------------------------------------------------------------------------------------------------------------finally 異常處理關鍵字,finally中的主體總會執行,不管異常發生是否。 2.1、當try中有return時執行順序 return語句並不是函式的最終出口,如果有finally語句,這在return之後還會執行finally (return的值會暫存在棧裡面,等待finally執行後再返回) 2.2 return和異常獲取語句的位置,具體情況如以下程式碼演示:

return和異常獲取語句的位置情況一(try中有return,finally中沒有return) 演示程式碼:

public class finallyDemo1 {
public static void main(String[] args) {
	
	System.out.println(test());
}
private static int test() {
	int num = 10;
	try {
		System.out.println("try");
		return num += 80;
	} catch (Exception e) {

	} finally {
		if (num > 20) {
			System.out.println("num > 20"+":"+num);
		}
		System.out.println("finally");
	}
	return num;
}

} 輸出結果:在這裡插入圖片描述

出現該結果的原因是: “return num += 80”被拆分成了“num = num+80”和“return num”兩個語句,先執行try中的“num =num+80”語句,將其儲存起來,在try中的”return num“執行前,先將finally中的語句執行完,而後再將90返回。

------------------------------------------------------------------------------------------------------------------return和異常獲取語句的位置情況二(try和finally中均有return) 程式碼演示:

public class finallyDemo2 {
	public static void main(String[] args) {
		System.out.println(test());
	}

	// try中的return被”覆蓋“掉了,不再執行。
	private static int test() {
		int num = 10;
		try {
			System.out.println("try");
			return num += 80;
		} catch (Exception e) {

		} finally {
			if (num > 20) {
				System.out.println("num > 20"+":"+num);
			}
			System.out.println("finally");
			return 100;
		}
	}
}

輸出結果:在這裡插入圖片描述

出現該結果的原因是: try中的return被"覆蓋"掉了,不再執行。

------------------------------------------------------------------------------------------------------------------return和異常獲取語句的位置情況三(finally中改變返回值num) 程式碼演示:

public class finallyDemo3 {
	public static void main(String[] args) {
		System.out.println(test());
	}
	
	private static int test() {
		int num = 10;
		try {
			System.out.println("try");
			return num;
		} catch (Exception e) {

		} finally {
			if (num > 20) {
				System.out.println("num > 20"+":"+num);
			}
			System.out.println("finally");
			num = 100;
		}
		return num;
	}
}

輸出結果:在這裡插入圖片描述

出現該結果的原因是: 雖然在finally中改變了返回值num,但因為finally中沒有return該num的值,因此在執行完finally中的語句後,test()方法會得到try中返回的num的值,而try中的num的值依然是程式進入finally程式碼塊前保留下來的值,因此得到的返回值為10。並且函式最後面的return語句不會執行。

------------------------------------------------------------------------------------------------------------------return和異常獲取語句的位置情況三另外一種情況:將num的值包裝在Num類中 程式碼演示:

public class finallyDemo4 {

	public static void main(String[] args) {
		
		System.out.println(test().num);
	}

	private static Num test() {
		Num number = new Num();
		try {
			System.out.println("try");
			return number;
		} catch (Exception e) {

		} finally {
			if (number.num > 20) {
				System.out.println("number.num > 20"+":"+number.num);
			}
			System.out.println("finally");
			number.num = 100;
		}
		return number;
	}
}

class Num {
	public int num = 10;
}

輸出結果:在這裡插入圖片描述

return和異常獲取語句的位置簡單地總結如下: try語句在返回前,將其他所有的操作執行完,保留好要返回的值,而後轉入執行finally中的語句,而後分為以下三種情況: 情況一:如果finally中有return語句,則會將try中的return語句”覆蓋“掉,直接執行finally中的return語句,得到返回值,這樣便無法得到try之前保留好的返回值。 情況二:如果finally中沒有return語句,也沒有改變要返回值,則執行完finally中的語句後,會接著執行try中的return語句,返回之前保留的值。 情況三:如果finally中沒有return語句,但是改變了要返回的值,這裡有點類似與引用傳遞和值傳遞的區別,分以下兩種情況: 如果return的資料是基本資料型別,則在finally中對該基本資料的改變不起作用,try中的return語句依然會返回進入finally塊之前保留的值。 如果return的資料是引用資料型別,而在finally中對該引用資料型別的屬性值的改變起作用,try中的return語句返回的就是在finally中改變後的該屬性的值。