final幕与、finally挑势、 finalize區(qū)別

  • final關(guān)鍵字:

  1. 可以將方法或者類聲明為final,明確告訴不可以被修改啦鸣。如Java類庫的一些基礎(chǔ)類中相當(dāng)一部分被聲明為final class潮饱,這樣做可以有效避免API使用者更改基礎(chǔ)功能,同樣也是保證平臺安全的必要手段赏陵。
  2. 使用final修飾參數(shù)或者變量饼齿,也可以清楚地避免意外賦值導(dǎo)致的邊城錯誤,甚至蝙搔,有人明確推薦將所有方法參數(shù)缕溉、本地變量、成員變量聲明成final吃型。
  3. Final變量產(chǎn)生了某種程度的不可變(immutable)的效果证鸥,所以可以用于保護(hù)只讀數(shù)據(jù),尤其是在并發(fā)編程中勤晚,因為明確地不能再賦值final變量枉层,有利于減少額外的同步開銷,也可以省去一些防御性拷貝的必要赐写。
  4. Final 也許會有性能的好處鸟蜡, 可以利用final幫助JVM將方法進(jìn)行內(nèi)聯(lián),可以改善編譯器進(jìn)行條件編譯的能力等等挺邀。但這些僅僅是基于假設(shè)得出的結(jié)論揉忘,比如JVM(Hotspot)判斷內(nèi)聯(lián)未必依賴final的提示,以及還有很多類似的端铛,final字段對性能的影響泣矛,大部分情況可以忽略。
  5. 在實際開發(fā)場景中禾蚕,除非特別考慮性能環(huán)節(jié)您朽,不然最好不要指望這種小技巧帶來的所謂性能好處,程序本身就應(yīng)該體現(xiàn)它的語義目的换淆。
  • finally關(guān)鍵字:

  1. 明確知道如何使用finally
  2. 需要關(guān)閉的鏈接等資源哗总,可以使用Java7中添加的try-with-resources語句几颜,通常情況下Java平臺本身可以更好的處理異常情況,編碼量也要少很多
  • finalize關(guān)鍵字:

  1. 明確知道已經(jīng)不推薦使用魂奥,并且Java9將Object.finalize()標(biāo)記為deprecated,
  2. 不要指望利用finalize來資源回收菠剩,因為我們無法保證finalize什么時候執(zhí)行,執(zhí)行的是否符合預(yù)期耻煤,使用不當(dāng)還會影響性能具壮,導(dǎo)致程序死鎖、掛起等哈蝇。
  • finalize的問題棺妓?真的那么不好用?

  1. 為啥導(dǎo)致不好用?finalize的執(zhí)行是和垃圾收集關(guān)聯(lián)在一起的炮赦,一旦實現(xiàn)了非空的finalize方法怜跑,就會導(dǎo)致相應(yīng)對象回收呈現(xiàn)數(shù)量級上的變慢,benchmark顯示大概會有40~50倍的下降吠勘。
  2. finalize被設(shè)計成災(zāi)對象被垃圾回收前調(diào)用性芬,就是意味著實現(xiàn)了finalize的方法的對象是“特殊公民”,JVM要懟它進(jìn)行額外處理剧防。finalize本質(zhì)上成為了快速回收的阻礙者植锉,可能導(dǎo)致你的對象經(jīng)過多個垃圾收集周期才能被收回
  3. System.runFinalization()告訴JVM積極一點,是不是就可以滿足快速垃圾回收峭拘,但這種方式本身是不可預(yù)測情況發(fā)生的俊庇,并且不能保證,所以在本質(zhì)上不能指望這么操作以解決問題鸡挠,現(xiàn)實環(huán)境中辉饱,由于finalize拖慢垃圾收集,導(dǎo)致大量對象堆積拣展,也是一種典型的導(dǎo)致OOM的原因
  4. 不要指望利用finalize來資源回收彭沼,因為我們無法保證finalize什么時候執(zhí)行,執(zhí)行的是否符合預(yù)期备埃,使用不當(dāng)還會影響性能溜腐,導(dǎo)致程序死鎖、掛起等瓜喇。
  • final可以用來修飾類、方法歉糜、變量乘寒,分別有不同的意義,final修飾的class代表不可以繼承擴(kuò)展匪补,final的變量是不可以修改的伞辛,而final的方法也是不可以重寫的(override)
  • finally則是Java保證重點代碼一定要被執(zhí)行的一種機(jī)制烂翰。我們可以使用try-finally或者try-catch-finally來進(jìn)行類似關(guān)閉JDBC連接、保證unlock鎖等操作
  • finalize是基礎(chǔ)類Java.lang.Object的一個方法蚤氏,它的設(shè)計目的是保證對象在被垃圾收集前完成特定資源的回收甘耿。finalize機(jī)制現(xiàn)在已經(jīng)不推薦使用,并且在JDK9開始被標(biāo)記deprecated
  • 問題:從概念上理解語法規(guī)范上的理解就是以上說法竿滨,但從全面的只是體系出發(fā)分析圍繞性能佳恬、并發(fā)、對象生命周期或垃圾收集基本過程等方面的理解

  • 擴(kuò)展情況

  1. 注意1.final不是immutable(不可變)
  final List<String> strList = new ArrayList<>();
  strList.add(“hello”);
  strList.add(“world”);
  List<String> unmodifiableStrList = List.of(“hello”, “world”);
  unmodifiableStrList.add(“agin”);
  • final只能約束strList這個引用不可以被賦值于游,但是strList對象行為不被final影響毁葱,添加元素等操作完全正常的。如果我們真的希望對象本身是不可變的贰剥,那么需要相應(yīng)的類支持不可變的行為倾剿。在上面這個例子中,List.of方法創(chuàng)建的本身就是不可變的List蚌成,最后那句add是會在運(yùn)行時拋出異常的前痘。
  • Immutable在很多場景是很好的選擇,Java目前沒有原生的不可變支持担忧,如果要實現(xiàn)immutable的類芹缔,我們需要滿足一下條件:
  1. 將class自身聲明為final,這樣別人就不能擴(kuò)展來繞過限制了
  2. 將所有成員變量定義為private和final涵妥,且不要實現(xiàn)setter方法
  3. 通常構(gòu)造對象時乖菱,成員變量使用深度拷貝來初始化,而不是直接賦值蓬网,這是一種防御措施窒所,因為這個環(huán)節(jié)無法確定輸入對象不被其他人修改。
  4. 如果確實需要實現(xiàn)getter方法帆锋,或者其他可能會返回內(nèi)部狀態(tài)的方法吵取,使用copy-on-write原則,創(chuàng)建私有的copy
  • 關(guān)于setter锯厢、getter方法皮官,建議最好是確定需要再生成
  • finalize的替代方案:

  1. Cleaner的實現(xiàn)利用了幻象引用(PhantomReference)這是一種常見的post-mortem 清理機(jī)制,利用幻象引用和引用隊列实辑,我們可以保證對象被徹底銷毀前做一些類似資源回收的工作捺氢,比如關(guān)閉文件描述符,這種方式比finalize更輕量剪撬、更加可靠一點
  2. 每個Cleaner的操作都是獨立的摄乒,有自己的運(yùn)行線程,這樣也就避免意外死鎖等問題
  3. 雖然如此,但Cleaner或者幻象引用改善的成仍然有限的馍佑,如果由于種種原因?qū)е禄孟笠枚逊e斋否,同樣會出現(xiàn)問題。所以Cleaner適合作為一種最后的保證手段拭荤,不能完全依賴
  4. 常見的使用幻象引用機(jī)制有MYSQL JDBC driver之一的mysql-connector-j,幻象引用也可以進(jìn)行類似鏈條式依賴關(guān)系的動作茵臭,比如,進(jìn)行總量控制的場景舅世,保證只有連接被關(guān)閉旦委,相應(yīng)資源被回收,連接池才能創(chuàng)建新的連接

總結(jié)Summary

  • 一般情況歇终,利用try-with-resourcs 或者try-finally機(jī)制社证,是非常好的回收資源的辦法。如果特殊情況需要額外處理评凝,可以考慮Java提供的Cleaner機(jī)制或者其他替代方法
  • 回收資源是因為資源都是有限的追葡,垃圾收集時間的不可預(yù)測,可能會機(jī)打家具資源占用奕短。這意味著對于消耗非常高頻的資源宜肉,不能通過finalize去承擔(dān)資源釋放的主要職責(zé),最多讓finalize作為最后的守門員翎碑,況且它已經(jīng)被實踐中暴露出問題谬返,所以建議資源用完即顯式釋放,或者利用資源池來盡量重用日杈。
  • 不要在finally中使用return語句



    final遣铝、finally、 finalize區(qū)別筆記
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末莉擒,一起剝皮案震驚了整個濱河市酿炸,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌涨冀,老刑警劉巖填硕,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異鹿鳖,居然都是意外死亡扁眯,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進(jìn)店門翅帜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來姻檀,“玉大人,你說我怎么就攤上這事涝滴∈└遥” “怎么了周荐?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長僵娃。 經(jīng)常有香客問我,道長腋妙,這世上最難降的妖魔是什么默怨? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮骤素,結(jié)果婚禮上匙睹,老公的妹妹穿的比我還像新娘。我一直安慰自己济竹,他們只是感情好痕檬,可當(dāng)我...
    茶點故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著送浊,像睡著了一般梦谜。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上袭景,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天唁桩,我揣著相機(jī)與錄音,去河邊找鬼耸棒。 笑死荒澡,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的与殃。 我是一名探鬼主播单山,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼幅疼!你這毒婦竟也來了米奸?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤衣屏,失蹤者是張志新(化名)和其女友劉穎躏升,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體狼忱,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡膨疏,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了钻弄。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片佃却。...
    茶點故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖窘俺,靈堂內(nèi)的尸體忽然破棺而出饲帅,到底是詐尸還是另有隱情复凳,我是刑警寧澤,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布灶泵,位于F島的核電站育八,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏赦邻。R本人自食惡果不足惜髓棋,卻給世界環(huán)境...
    茶點故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望惶洲。 院中可真熱鬧按声,春花似錦、人聲如沸恬吕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽铐料。三九已至渐裂,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間余赢,已是汗流浹背芯义。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留妻柒,地道東北人扛拨。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像举塔,于是被迫代替她去往敵國和親绑警。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,619評論 2 354

推薦閱讀更多精彩內(nèi)容