【Java】final、finally、finalize

final、finally與finalize的區別

  • final:final是一個修飾符,可以修飾類,方法和變量。final修飾類表示類不能被其它類繼承,並且該類中的所有方法都會隱式的被final修飾。final修飾方法,則該方法不能被重寫,若父類中final方法的訪問權限爲private,將導致子類中不能直接繼承該方法,因此,此時可以在子類中定義相同方法名的函數,此時不會與重寫final的矛盾,而是在子類中重新地定義了新方法。當final修飾一個基本數據類型時,表示該基本數據類型的值一旦在初始化後便不能發生變化;如果final修飾一個引用類型時,則在對其初始化之後便不能再讓其指向其他對象了,但該引用所指向的對象的內容是可以發生變化的。本質上是一回事,因爲引用的值是一個地址,final要求值,即地址的值不發生變化。
  • finally:finally作爲異常處理的一部分,它只能用在try/catch語句中,並且附帶一個語句塊,表示這段語句最終一定會被執行(不管有沒有拋出異常),經常被用在需要釋放資源的情況下。但須注意,在某些特殊情況下,finally塊是不會執行的。
  • finalize:finalize()是Object中定義的一個方法,也就是每個對象都有這個方法。當垃圾回收器確定不存在對該對象的更多引用時(是個垃圾),由對象的垃圾回收器調用此方法。子類重寫 finalize 方法,以配置系統資源或執行其他清除,例如:一個socket鏈接,在對象初始化時創建,整個生命週期內有效,那麼就需要實現finalize,關閉這個鏈接。 finalize的用法

try-catch-finally中try塊中有return,finally還會執行嗎?

會執行,當我們執行到return之後,我們不會立即返回,而是會接着執行finally塊裏面的代碼,只有執行完,纔會繼續執行我們的return值。

1、不管有沒有異常,finally中的代碼都會執行
2、當try、catch中有return時,finally中的代碼依然會繼續執行
3、finally是在return後面的表達式運算之後執行的,此時並沒有返回運算之後的值,而是把值保存起來,不管finally對該值做任何的改變,返回的值都不會改變,依然返回保存起來的值。也就是說方法的返回值是在finally運算之前就確定了的。
4、如果return的數據是引用數據類型,而在finally中對該引用數據類型的屬性值的改變起作用,try中的return語句返回的就是在finally中改變後的該屬性的值。
5、finally代碼中最好不要包含return,程序會提前退出,也就是說返回的值不是try或catch中的值。

哪些特殊情況下,finally塊不會執行?

除非在try塊或者catch塊中調用了退出虛擬機的方法(即System.exit(1);),否則不管在try塊、catch塊中執行怎樣的代碼,出現怎樣的情況,異常處理的finally塊總是會被執行的。

不過,一般情況下,不要再finally塊中使用return或throw等導致方法終止的語句,因爲一旦使用,將會導致try塊、catch塊中的return、throw語句失效。

 

總結一下這個小問題:

當程序執行try塊,catch塊時遇到return語句或者throw語句,這兩個語句都會導致該方法立即結束,所以系統並不會立即執行這兩個語句,而是 去尋找該異常處理流程中的finally塊,如果沒有finally塊,程序立即執行return語句或者throw語句,方法終止。如果有 finally塊,系統立即開始執行finally塊,只有當finally塊執行完成後,系統纔會再次跳回來執行try塊、catch塊裏的 return或throw語句,如果finally塊裏也使用了return或throw等導致方法終止的語句,則finally塊已經終止了方法,不用 再跳回去執行try塊、catch塊裏的任何代碼了。

綜上:儘量避免在finally塊裏使用return或throw等導致方法終止的語句,否則可能出現一些很奇怪的情況!

使用throws拋出異常的思路是:當前方法不知道如何處理這種類型的異常,該異常應該由上一級調用者處理,如果main方法也不知道應該如何處理這種類型的異常,也可以使用使用throws聲明拋出異常,該異常將交給JVM來處理。

JVM對異常的處理方法:打印異常跟蹤棧的信息,並終止程序運行,所以有很多程序遇到異常後自動結束。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章