當前位置:首頁 » 編程語言 » javafinalize

javafinalize

發布時間: 2022-11-03 05:26:04

A. java里finalize()方法是干什麼用的

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

B. 為什麼在Java中不使用finalize方法

Java提供finalize()方法,垃圾回收器准備釋放內存的時候,會先調用finalize()。
(1).對象不一定會被回收。
(2).垃圾回收不是析構函數。
(3).垃圾回收只與內存有關。
(4).垃圾回收和finalize()都是靠不住的,只要JVM還沒有快到耗盡內存的地步,它是不會浪費時間進行垃圾回收的。
有時當撤消一個對象時,需要完成一些操作。例如,如果一個對象正在處理的是非Java 資源,如文件句柄或window 字元字體,這時你要確認在一個對象被撤消以前要保證這些資源被釋放。為處理這樣的狀況,Java 提供了被稱為收尾(finalization )的機制。使用該機制你可以定義一些特殊的操作,這些操作在一個對象將要被垃圾回收程序釋放時執行。
要給一個類增加收尾(finalizer ),你只要定義finalize ( ) 方法即可。Java 回收該類的一個對象時,就會調用這個方法。在finalize ( )方法中,你要指定在一個對象被撤消前必須執行的操作。垃圾回收周期性地運行,檢查對象不再被運行狀態引用或間接地通過其他對象引用。就在對象被釋放之前,Java 運行系統調用該對象的finalize( ) 方法。
finalize()方法的通用格式如下:
protected void finalize( )
{
// finalization code here
}

其中,關鍵字protected是防止在該類之外定義的代碼訪問finalize()標識符。該標識符和其他標識符將在第7章中解釋。
理解finalize( ) 正好在垃圾回收以前被調用非常重要。例如當一個對象超出了它的作用域時,finalize( ) 並不被調用。這意味著你不可能知道何時——甚至是否——finalize( ) 被調用。因此,你的程序應該提供其他的方法來釋放由對象使用的系統資源,而不能依靠finalize( ) 來完成程序的正常操作。
注意:如果你熟悉C ,那你知道C 允許你為一個類定義一個撤消函數(destructor ),它在對象正好出作用域之前被調用。Java不支持這個想法也不提供撤消函數。finalize() 方法只和撤消函數的功能接近。當你對Java 有豐富經驗時,你將看到因為Java使用垃圾回收子系統,幾乎沒有必要使用撤消函數。
理解finalize()-析構函數的替代者
by Tim Gooch
在許多方面,Java 類似於 C++。Java 的語法非常類似於 C++,Java 有類、方法和數據成員;Java 的類有構造函數; Java 有異常處理。
但是,如果你使用過 C++ 會發現 Java 也丟掉一些可能是你熟悉的特性。這些特性之一就是析構函數。取代使用析構函數,Java 支持finalize() 方法。
在本文中,我們將描述 finalize() 與 C++ 析構函數的區別。另外,我們將創建一個簡單的 Applet 來演示 finalize() 是如何工作的。
最終的界限
與 Java 不同,C++ 支持局部對象(基於棧)和全局對象(基於堆)。因為這一雙重支持,C++ 也提供了自動構造和析構,這導致了對構造函數和析構函數的調用,(對於堆對象)就是內存的分配和釋放。
在 Java 中,所有對象都駐留在堆內存,因此局部對象就不存在。結果,Java 的設計者覺得不需要析構函數(象 C++ 中所實現的)。
取而代之,Java 定義了一個特殊的方法叫做finalize() ,它提供了 C++ 析構函數的一些功能。但是,finalize() 並不完全與 C++ 的析構函數一樣,並可以假設它會導致一系列的問題。finalize() 方法作用的一個關鍵元素是 Java 的垃圾回收器。
垃圾回收器
在 C/C++、Pascal和其他幾種多種用途的編程語言中,開發者有責任在內存管理上發揮積極的作用。例如,如果你為一個對象或數據結構分配了內存,那麼當你不再使用它時必須釋放掉該內存。
在 Java 中,當你創建一個對象時,Java 虛擬機(JVM)為該對象分配內存、調用構造函數並開始跟蹤你使用的對象。當你停止使用一個對象(就是說,當沒有對該對象有效的引用時),JVM 通過垃圾回收器將該對象標記為釋放狀態。
當垃圾回收器將要釋放一個對象的內存時,它調用該對象的finalize() 方法(如果該對象定義了此方法)。垃圾回收器以獨立的低優先順序的方式運行,只有當其他線程掛起等待該內存釋放的情況出現時,它才開始運行釋放對象的內存。(事實上,你可以調用System.gc() 方法強制垃圾回收器來釋放這些對象的內存。)
在以上的描述中,有一些重要的事情需要注意。首先,只有當垃圾回收器釋放該對象的內存時,才會執行finalize()。如果在 Applet 或應用程序退出之前垃圾回收器沒有釋放內存,垃圾回收器將不會調用finalize()。
其次,除非垃圾回收器認為你的 Applet 或應用程序需要額外的內存,否則它不會試圖釋放不再使用的對象的內存。換句話說,這是完全可能的:一個 Applet 給少量的對象分配內存,沒有造成嚴重的內存需求,於是垃圾回收器沒有釋放這些對象的內存就退出了。
顯然,如果你為某個對象定義了finalize() 方法,JVM 可能不會調用它,因為垃圾回收器不曾釋放過那些對象的內存。調用System.gc() 也不會起作用,因為它僅僅是給 JVM 一個建議而不是命令。
結論
然而有益的是,Java 的自動垃圾回收器不會失去平衡。作為便利的代價,你不得不放棄對系統資源釋放的控制。不象 C++ 中的析構函數,Java Applet 不會自動執行你的類中的finalize() 方法。事實上,如果你正在使用 Java 1.0,即使你試圖強制它調用finalize() 方法,也不能確保將調用它。
因此,你不應當依靠finalize() 來執行你的 Applet 和應用程序的資源清除工作。取而代之,你應當明確的清除那些資源或創建一個try...finally 塊(或類似的機制)來實現。

finalize方法是與Java編程中的垃圾回收器有關系。即:當一個對象變成一個垃圾對象的時候,如果此對象的內存被回收,那麼就可以調用系統中定義的finalize方法來完成

當然,Java的內存回收可以由JVM來自動完成。如果你手動使用,則可以使用上面的方法。

舉例說明:

C. java中finalize()方法在哪個類中

它是在 Object 類中定義的,因此所有的類都繼承了它。子類覆蓋 finalize() 方法以整理系統資源或者執行其他清理工作。finalize() 方法是在垃圾收集器刪除對象之前對這個對象調用的。

D. 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()方法,它跟析構函數不一樣。

E. 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引用,重生。

(5)javafinalize擴展閱讀:

盡量避免使用finalize():

1、finalize()不一定會被調用, 因為java的垃圾回收器的特性就決定了它不一定會被調用。

2、就算finalize()函數被調用, 它被調用的時間充滿了不確定性, 因為程序中其他線程的優先順序遠遠高於執行finalize()函數線程的優先順序。也許等到finalize()被調用, 資料庫的連接池或者文件句柄早就耗盡了。

3、如果一種未被捕獲的異常在使用finalize方法時被拋出,這個異常不會被捕獲,finalize方法的終結過程也會終止,造成對象出於破壞的狀態。被破壞的對象又很可能導致部分資源無法被回收, 造成浪費。

4、finalize()函數和垃圾回收器的運行本身就要耗費資源, 也許會導致程序的暫時停止。

F. Java中final,finally和finalize的區別是什麼

一、final :
1、修飾符(關鍵字) 如果一個類被聲明為final,意味著它不能再派生新的子類,不能作為父類被繼承。因此一個類不能及被聲明為abstract,又被聲明為final的。
2、將變數或方法聲明為final,可以保證他們使用中不被改變。被聲明為final的變數必須在聲明時給定初值,而以後的引用中只能讀取,不可修改,被聲明為final的方法也同樣只能使用,不能重載。
二、finally:
在異常處理時提供finally塊來執行清楚操作。如果拋出一個異常,那麼相匹配的catch語句就會執行,然後控制就會進入finally塊,如果有的話。
三、finalize:
是方法名。java技術允許使用finalize()方法在垃圾收集器將對象從內存中清除之前做必要的清理工作。這個方法是在垃圾收集器在確定了,被清理對象沒有被引用的情況下調用的。
finalize是在Object類中定義的,因此,所有的類都繼承了它。子類可以覆蓋finalize()方法,來整理系統資源或者執行其他清理工作。

G. java中finalize()方法的使用

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

可從本書支持網站下載的示常式序GarbageCollection使用下列代碼演示了Finalize方法:

Public Class Form1 Public Running As Boolean Private Class Junk Public MyForm As Form1 Public Sub New(ByVal my_form As Form1) MyForm = my_form End Sub ' Garbage collection started. Protected Overrides Sub Finalize() ' Stop making objects. MyForm.Running = False End Sub End Class ' Make objects until garbage collection starts. Private Sub btnCreateObjects_Click() Handles btnCreateObjects.Click Running = True Dim new_obj As Junk Dim max_i As Long For i As Long = 1 To 100000 new_obj = New Junk(Me) If Not Running Then max_i = i Exit For End If Next i MessageBox.Show("Allocated " & max_i.ToString & " objects") End Sub End Class Form1類先定義公有變數Running,然後定義Junk類,該類包含引用Form1類的變數。Junk類的構造函數保存創建它的Form1對象的引用,它的Finalize方法設置Form1對象的Running值為False。

H. java中finalize方法中的代碼為什麼不保證一定執行

finalize方法是對象被垃圾收集器清理的時候調用的
除非你自己強制用System.gc()來調用垃圾收集器,否則你不可能知道什麼時候系統會自己調用垃圾收集器 也就不可能保證會調用finalize方法

I. java為什麼不推薦finalize方法

你不知道什麼時候對象會被清除,對象清除你是完全無法預知控制的。如果你寫了
finalize方法將會在對象清除的時候調用,而這個調用是很不確定的(他可能在你程序執行某個
特殊任務時執行,而其中任務與finalize方法存在沖突,給你報告一個莫名其妙的錯誤,甚至每
一次錯誤還不一樣,你可以想一下有多可怕),這就為程序帶來不穩定因
素,也許會給你帶來意想不到的錯誤,所以強烈建議不使用,除非特殊情況。

J. Java中的finalize()方法

看到你這段代碼之後就感覺特別熟悉,好像在哪裡見過,後來翻書一看原來是ThinkinginJava里的一段小例子。
finalize()一般是用不到的,除非JVM認為已經沒有內存可以使用了,那時JVM才會消耗資源去清理垃圾,所以finalize()也不能作為通用的清理方法。而且finalize()有一個比較另類的用法,就是說finalize()並不依賴對它的直接調用,它有某些觸發機制,比如說對象已經標明要被終結,這時會自動執行finalize()。並不需要去顯式的調用,這也是為什麼代碼中沒有顯式調用finalize(),但它確實執行了的原因,因為它觸發了finalize()的執行條件。
其實不必太在意finalize(),因為一般的程序中是使用不到finalize()的,所以那些開發Java的大牛們把finalize()的用法整的很隱晦,而且它們把垃圾回收機製做的比較自動化,一般不需要手工清理。

熱點內容
python安裝後怎麼打開 發布:2025-01-10 11:08:35 瀏覽:870
phpjava架構 發布:2025-01-10 10:56:06 瀏覽:382
python二維排序 發布:2025-01-10 10:56:00 瀏覽:607
南水北調怎麼配置 發布:2025-01-10 10:55:27 瀏覽:121
廣數980系統參數密碼是多少 發布:2025-01-10 10:55:25 瀏覽:577
androidhtml字體 發布:2025-01-10 10:55:01 瀏覽:787
資料庫連接工廠模式 發布:2025-01-10 10:51:00 瀏覽:487
mac文件夾路徑設置 發布:2025-01-10 10:48:12 瀏覽:803
shell腳本自動密碼 發布:2025-01-10 10:46:29 瀏覽:766
安卓手機怎麼切兩個屏 發布:2025-01-10 10:33:51 瀏覽:684