本文目錄一覽:
- 1、Java中final,finally和finalize的區別是什麼?
- 2、java中的finalize()方法怎麼用
- 3、java中final,finally和finalize的區別
- 4、java中finalize()方法的使用
- 5、java 中的finalize怎麼用啊?
Java中final,finally和finalize的區別是什麼?
一、final :
1、修飾符(關鍵字) 如果一個類被聲明為final,意味著它不能再派生新的子類,不能作為父類被繼承。因此一個類不能及被聲明為abstract,又被聲明為final的。
2、將變數或方法聲明為final,可以保證他們使用中不被改變。被聲明為final的變數必須在聲明時給定初值,而以後的引用中只能讀取,不可修改,被聲明為final的方法也同樣只能使用,不能重載。
二、finally:
在異常處理時提供finally塊來執行清楚操作。如果拋出一個異常,那麼相匹配的catch語句就會執行,然後控制就會進入finally塊,如果有的話。
三、finalize:
是方法名。java技術允許使用finalize()方法在垃圾收集器將對象從內存中清除之前做必要的清理工作。這個方法是在垃圾收集器在確定了,被清理對象沒有被引用的情況下調用的。
finalize是在Object類中定義的,因此,所有的類都繼承了它。子類可以覆蓋finalize()方法,來整理系統資源或者執行其他清理工作。
java中的finalize()方法怎麼用
類的finalize()方法,可以告訴垃圾回收器應該執行的操作,該方法從Object類繼承而來。
在從堆中永久刪除對象之前,垃圾回收器調用該對象的finalize()方法。注意,無法確切地保證垃圾回收器何時調用該方法,也無法保證調用不同對象的方法的順序。即使一個對象包含另一個對象的引用,或者在釋放一個對象很久以前就釋放了另一個對象,也可能會以任意的順序調用這兩個對象的Finalize方法。如果必須保證採用特定的順序,則必須提供自己的特有清理方法。
java中final,finally和finalize的區別
1. final
在java中,final可以用來修飾類,方法和變數(成員變數或局部變數)。下面將對其詳細介紹。
1.1 修飾類
當用final修飾類的時,表明該類不能被其他類所繼承。當我們需要讓一個類永遠不被繼承,此時就可以用final修飾,但要注意:
final類中所有的成員方法都會隱式的定義為final方法。
1.2 修飾方法
使用final方法的原因主要有兩個:
(1) 把方法鎖定,以防止繼承類對其進行更改。
(2) 效率,在早期的java版本中,會將final方法轉為內嵌調用。但若方法過於龐大,可能在性能上不會有多大提升。因此在最近版本中,不需要final方法進行這些優化了。
final方法意味著「最後的、最終的」含義,即此方法不能被重寫。
注意:若父類中final方法的訪問許可權為private,將導致子類中不能直接繼承該方法,因此,此時可以在子類中定義相同方法名的函數,此時不會與重寫final的矛盾,而是在子類中重新地定義了新方法。
1.3 修飾變數
final成員變數表示常量,只能被賦值一次,賦值後其值不再改變。類似於C++中的const。
當final修飾一個基本數據類型時,表示該基本數據類型的值一旦在初始化後便不能發生變化;如果final修飾一個引用類型時,則在對其初始化之後便不能再讓其指向其他對象了,但該引用所指向的對象的內容是可以發生變化的。本質上是一回事,因為引用的值是一個地址,final要求值,即地址的值不發生變化。
final修飾一個成員變數(屬性),必須要顯示初始化。這裡有兩種初始化方式,一種是在變數聲明的時候初始化;第二種方法是在聲明變數的時候不賦初值,但是要在這個變數所在的類的所有的構造函數中對這個變數賦初值。
當函數的參數類型聲明為final時,說明該參數是只讀型的。即你可以讀取使用該參數,但是無法改變該參數的值。
2. finally
finally作為異常處理的一部分,它只能用在try/catch語句中,並且附帶一個語句塊,表示這段語句最終一定會被執行(不管有沒有拋出異常),經常被用在需要釋放資源的情況下。(×)(這句話其實存在一定的問題)
很多人都認為finally語句塊一定會執行,但真的是這樣么?答案是否定的,例如下面這個例子:
只有與finally對應的try語句塊得到執行的情況下,finally語句塊才會執行。以上兩種情況在執行try語句塊之前已經返回或拋出異常,所以try對應的finally語句並沒有執行。
3. finalize
finalize()是在java.lang.Object里定義的,也就是說每一個對象都有這麼個方法。這個方法在gc啟動,該對象被回收的時候被調用。其實gc可以回收大部分的對象(凡是new出來的對象,gc都能搞定,一般情況下我們又不會用new以外的方式去創建對象),所以一般是不需要程序員去實現finalize的。
特殊情況下,需要程序員實現finalize,當對象被回收的時候釋放一些資源,比如:一個socket鏈接,在對象初始化時創建,整個生命周期內有效,那麼就需要實現finalize,關閉這個鏈接。
使用finalize還需要注意一個事,調用super.finalize();
一個對象的finalize()方法只會被調用一次,而且finalize()被調用不意味著gc會立即回收該對象,所以有可能調用finalize()後,該對象又不需要被回收了,然後到了真正要被回收的時候,因為前面調用過一次,所以不會調用finalize(),產生問題。 所以,推薦不要使用finalize()方法,它跟析構函數不一樣。
java中finalize()方法的使用
設計一個對象重生的代碼來演示,如下:
具體解析如下:
為方便起見, 把a,b兩個變數所指的內存空間就叫做a和b。
A a = new A(new B(“allen” , 20)) ; //此時a和b都是reachable, unfinalized狀態。
a = null ;
這之後, a和b的狀態會在某一個時刻變成unreachable, unfinalized或者a和b直接變成f-reachable, unfianlized。
然後在某個時刻,GC檢測到a和b處於unfinalized狀態,就將他們添加到F-queue,並將狀態改為f-reachable finalizable。
之後分兩種情況:
1、 GC從F-queue中首先取出a, 並被某個線程執行了finalize(), 也就相當於被某個活動的線程持有, a狀態變成了reachable, finalized.。
此時由於a被c對象所引用,所以之後不會變成unreachable finalized而被銷毀(重生) 與此同時,b由於一直被a所引用,,所以b的狀態變成了reachable, finalizable.。
然後在某個時刻被從F-queue取出, 變成reachable, finalized狀態。
2、GC從F-queue中首先取出b,並被某個線程執行了finalize(), 狀態變成reachable finalized. 然後a也類似, 變成reachable finalized狀態, 並被c引用,重生。
擴展資料:
盡量避免使用finalize():
1、finalize()不一定會被調用, 因為java的垃圾回收器的特性就決定了它不一定會被調用。
2、就算finalize()函數被調用, 它被調用的時間充滿了不確定性, 因為程序中其他線程的優先順序遠遠高於執行finalize()函數線程的優先順序。也許等到finalize()被調用, 資料庫的連接池或者文件句柄早就耗盡了。
3、如果一種未被捕獲的異常在使用finalize方法時被拋出,這個異常不會被捕獲,finalize方法的終結過程也會終止,造成對象出於破壞的狀態。被破壞的對象又很可能導致部分資源無法被回收, 造成浪費。
4、finalize()函數和垃圾回收器的運行本身就要耗費資源, 也許會導致程序的暫時停止。
參考資料:
百度百科–finalize
java 中的finalize怎麼用啊?
java的finalize的使用方式如下:
1.所有對象被Garbage Collection時自動調用,比如運行System.gc()的時候.
2.程序退出時為每個對象調用一次finalize方法。
3.顯式的調用finalize方法
除此以外,正常情況下,當某個對象被系統收集為無用信息的時候,finalize()將被自動調用,但是jvm不保證finalize()一定被調用,也就是說,finalize()的調用是不確定的,這也就是為什麼sun不提倡使用finalize()的原因
有時當撤消一個對象時,需要完成一些操作。例如,如果一個對象正在處理的是非Java 資源,如文件句柄或window 字元字體,這時你要確認在一個對象被撤消以前要保證這些資源被釋放。為處理這樣的狀況,Java 提供了被稱為收尾(finalization )的機制。使用該機制你可以定義一些特殊的操作,這些操作在一個對象將要被垃圾回收程序釋放時執行。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/236727.html