包含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

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-12 12:01
下一篇 2024-12-12 12:01

相關推薦

  • Java JsonPath 效率優化指南

    本篇文章將深入探討Java JsonPath的效率問題,並提供一些優化方案。 一、JsonPath 簡介 JsonPath是一個可用於從JSON數據中獲取信息的庫。它提供了一種DS…

    編程 2025-04-29
  • java client.getacsresponse 編譯報錯解決方法

    java client.getacsresponse 編譯報錯是Java編程過程中常見的錯誤,常見的原因是代碼的語法錯誤、類庫依賴問題和編譯環境的配置問題。下面將從多個方面進行分析…

    編程 2025-04-29
  • Java騰訊雲音視頻對接

    本文旨在從多個方面詳細闡述Java騰訊雲音視頻對接,提供完整的代碼示例。 一、騰訊雲音視頻介紹 騰訊雲音視頻服務(Cloud Tencent Real-Time Communica…

    編程 2025-04-29
  • Java Bean載入過程

    Java Bean載入過程涉及到類載入器、反射機制和Java虛擬機的執行過程。在本文中,將從這三個方面詳細闡述Java Bean載入的過程。 一、類載入器 類載入器是Java虛擬機…

    編程 2025-04-29
  • Java Milvus SearchParam withoutFields用法介紹

    本文將詳細介紹Java Milvus SearchParam withoutFields的相關知識和用法。 一、什麼是Java Milvus SearchParam without…

    編程 2025-04-29
  • Java 8中某一周的周一

    Java 8是Java語言中的一個版本,於2014年3月18日發布。本文將從多個方面對Java 8中某一周的周一進行詳細的闡述。 一、數組處理 Java 8新特性之一是Stream…

    編程 2025-04-29
  • Java判斷字元串是否存在多個

    本文將從以下幾個方面詳細闡述如何使用Java判斷一個字元串中是否存在多個指定字元: 一、字元串遍歷 字元串是Java編程中非常重要的一種數據類型。要判斷字元串中是否存在多個指定字元…

    編程 2025-04-29
  • VSCode為什麼無法運行Java

    解答:VSCode無法運行Java是因為默認情況下,VSCode並沒有集成Java運行環境,需要手動添加Java運行環境或安裝相關插件才能實現Java代碼的編寫、調試和運行。 一、…

    編程 2025-04-29
  • Java任務下發回滾系統的設計與實現

    本文將介紹一個Java任務下發回滾系統的設計與實現。該系統可以用於執行複雜的任務,包括可回滾的任務,及時恢復任務失敗前的狀態。系統使用Java語言進行開發,可以支持多種類型的任務。…

    編程 2025-04-29
  • Java 8 Group By 會影響排序嗎?

    是的,Java 8中的Group By會對排序產生影響。本文將從多個方面探討Group By對排序的影響。 一、Group By的概述 Group By是SQL中的一種常見操作,它…

    編程 2025-04-29

發表回復

登錄後才能評論