Effective Java 讀書筆記(1)

創(chuàng)建和銷毀對象


第一條:考慮用靜態(tài)工廠方法代替構造器

當該類需要返回不同的實例(子類實例),或者唯一一個實例(單例)時,應考慮用靜態(tài)工廠方法代替構造器。
靜態(tài)工廠方法的一些慣用名稱:

  • valueOf 返回的實例與參數有相同的值盒发,相當于類型轉換
  • of valueOf的簡化
  • getInstance 返回的實例是通過參數類描述的,但一般不具有與參數同樣的值狡逢。對于Singleton來說宁舰,無參數,返回唯一一個實例甚侣。
  • newInstance 類似于getInstance明吩,但每次返回新的實例
  • getType 在工廠方法處于不同的類時使用,Type指返回類型的類型
  • newType 同上

第二條:遇到多個構造器參數時要考慮用構建器

當創(chuàng)建對象面臨多個可選參數時(即殷费,構造器有多個可選的參數)印荔,有以下三種方案:

  • 重疊構造器模式
    根據參數的不同組合,編寫多個簽名不同的構造器或靜態(tài)工廠方法详羡。優(yōu)點:線程安全仍律,參數組合少時簡單;缺點:當參數量很大实柠,且其組合很多時水泉,代碼編寫麻煩且可讀性差
  • JavaBean模式
    調用一個構造器類創(chuàng)建對象并設置必要的參數,再通過setter方法類設置每個可選參數窒盐。優(yōu)點:實例簡單草则,代碼簡潔,可擴展性強蟹漓。缺點:構造過程被分為多個調用方法炕横,難以保證一致性,(多線程)易出錯難調試葡粒;無法實例化一個不可變對象(致命)
  • Builder模式
    不直接生成想要的對象份殿,而是先用必要的參數實例化一個builder,再用setter方法設置每個可選參數嗽交,最后調用無參的build方法來生成不可變的對象卿嘲。既能保證重疊構造器模式的安全性,也能保證像JavaBean一樣簡單可讀

第三條:用私有構造器或者枚舉類型強化Singleton屬性

實現Singleton有以下三種方法:

  • 將構造器私有化夫壁,將實例設為公有的靜態(tài)final成員拾枣。私有構造器只被調用一次,用來實例化單例:
public class FirstSingleton {
    public String message;
    public static final FirstSingleton INSTANCE = new FirstSingleton();

    private FirstSingleton(){
        message = "Hello World! First Singleton!";
    }
}

由于缺少公有的或者受保護的構造器盒让,所以保證了單例的全局唯一性放前。

注意:享有特權的客戶端可以借助AccessibleObject.setAccessibe方法忿磅,通過反射機制調用私有構造器。如果需要抵御這種攻擊凭语,可以修改私有構造器葱她,使其在構造第二個實例時拋出異常。

  • 公有的成員是個靜態(tài)工廠方法:
public class SecondSingleton {
    public String message;
    private static final SecondSingleton INSTANCE  = new SecondSingleton();
    private SecondSingleton(){
        message = "Hello World! Second Singleton!";
    }
    public static SecondSingleton getInstance(){
        return INSTANCE;
    }
}

對于靜態(tài)方法getInstance的所有調用似扔,都會返回同一個對象引用(上述注意依然使用)吨些。
公有域方法的主要好處在于,組成類的成員的聲明很清楚第表明了這個類是一個Singleton:公有的靜態(tài)域是final的炒辉,所以該域將總是包含相同的對象引用豪墅。

對于以上兩種方法,在序列化時黔寇,僅僅在聲明中加上implements Serializable是不夠的偶器。為了維護并保證Singleton,必須聲明所有的實例域都是瞬時的(transient)的缝裤,并提供一個readResove實例屏轰。否則,每次反序列化一個實例時憋飞,都會創(chuàng)建一個新的實例:

    private Object readResolve(){
        return INSTANCE;
    }
  • 編寫一個包含單個元素的枚舉類型:
    public enum ThirdSingleton {
    INSTANCE;
    public String message = "Hello World! Third Singleton!";
}

這種方法在功能上與公有域方法相近霎苗,但是其更加簡潔,無償地提供了序列化機制榛做,絕對防止多次實例化唁盏,即使是在面對復雜的序列化或者反射攻擊時。單元素的枚舉類型已經成為實現Singleton的最佳方法检眯。


第四條:通過私有化構造器強化不可實例的能力

有時候厘擂,我們需要編寫只包含靜態(tài)方法和靜態(tài)域的類。這些工具類不希望被實例化锰瘸,實例對它沒有任何意義驴党。這個時候,我們需要私有化構造器获茬,防止其在無意間被實例化。


第五條:避免創(chuàng)建不必要的對象

一般來說倔既,最好能重用對象而不是每次需要 的時候就創(chuàng)建一個相同功能的新對象恕曲。

  • 重用不可變對象:如果對象是不可變的,它就始終可以被重用(單例模式渤涌、String對象池)
  • 重用已知不會被修改的可變對象佩谣。創(chuàng)建某些對象的成本是十分昂貴的,且其在創(chuàng)建之后实蓬,其值一般不會改變茸俭,此時我們可以考慮重用這個對象已減少創(chuàng)建成本吊履。
  • 使用適配器(適配器是指這樣一個對象:它把功能委托給一個后備對象,從而為后備對象提供一個可以替代的接口)调鬓。如Map類的KeySet方法艇炎,它返回一個Set對象。對于一個Map而言腾窝,它的key是可變的缀踪,但是keySet對象是唯一的,只是其內容會發(fā)生變化虹脯。
  • 優(yōu)先使用基本類型而不是自動裝箱基本類型驴娃,當心無意識的自動裝箱。

第六條:消除過期的對象引用

在支持垃圾回收的語言中循集,內存泄漏是很隱蔽的唇敞,稱之為“無意識的對象保持(unintentional object retention)“更為恰當。如果一個對象被無意識保留起來咒彤,那么垃圾回收機制不僅不會去處理這個對象疆柔,而且不會處理這個對象所引用的所有其他對象,久而久之會對性能造成潛在的重大影響蔼紧。

這種問題一般出現在堆型豁、棧、數組氓栈、鏈表等數據結果在pop對象時沒有消除引用赡模,如size--;
這種問題的解決方法很簡單,一旦對象過期查吊,清空這些引用即可stack[size--] = null;

內存泄漏的常見來源:

  • 類自己管理內存谐区。當我們需要寫自己管理內存 的類時,如手動實現一個stack逻卖,應謹記一旦元素不需要用到宋列,要立即釋放(消除引用),以便垃圾回收機制能及時回收评也。
  • 緩存炼杖。緩存中的對象極易被遺忘。-> 使用WeakHashMap代表緩存
  • 監(jiān)聽器及其他回調盗迟。如果你實現了一個API坤邪,客戶端在這個API中注冊回調,卻沒有顯式取消注冊罚缕,那么除非你采取某些動作艇纺,否則它們就會被積聚。確保回調立即被當做立即回收的最佳方法是只保存它們的弱引用黔衡。

第七條:避免使用終結方法

終結方法(finalizer)通常是不可預測的蚓聘,也是很危險的。
終結方法通常在垃圾回收機制回收對象時負責執(zhí)行盟劫,其執(zhí)行時間取決于jvm設計夜牡、配置以及程序執(zhí)行過程。而且捞高,java規(guī)范并不保證終結方法一定會被執(zhí)行氯材。還有一點,使用終結方法會帶來嚴重的性能損耗硝岗。
若一個對象需要在其終結時進行某些動作氢哮,可以考慮使用顯式終結動作,并要求所有客戶端在結束該實例時調用該方法型檀,例如InputStream接口的close方法
終結方法的合法用途:

  • 充當顯式終結方法的“安全網(safety net)冗尤。
  • 終結非關鍵的本地資源(一般指本地對等體native peer),即本地對象胀溺。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末裂七,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子仓坞,更是在濱河造成了極大的恐慌背零,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,198評論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件无埃,死亡現場離奇詭異徙瓶,居然都是意外死亡,警方通過查閱死者的電腦和手機嫉称,發(fā)現死者居然都...
    沈念sama閱讀 94,334評論 3 398
  • 文/潘曉璐 我一進店門侦镇,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人织阅,你說我怎么就攤上這事壳繁。” “怎么了荔棉?”我有些...
    開封第一講書人閱讀 167,643評論 0 360
  • 文/不壞的土叔 我叫張陵闹炉,是天一觀的道長。 經常有香客問我润樱,道長渣触,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,495評論 1 296
  • 正文 為了忘掉前任祥国,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘舌稀。我一直安慰自己啊犬,他們只是感情好,可當我...
    茶點故事閱讀 68,502評論 6 397
  • 文/花漫 我一把揭開白布壁查。 她就那樣靜靜地躺著觉至,像睡著了一般。 火紅的嫁衣襯著肌膚如雪睡腿。 梳的紋絲不亂的頭發(fā)上语御,一...
    開封第一講書人閱讀 52,156評論 1 308
  • 那天,我揣著相機與錄音席怪,去河邊找鬼应闯。 笑死,一個胖子當著我的面吹牛挂捻,可吹牛的內容都是我干的碉纺。 我是一名探鬼主播,決...
    沈念sama閱讀 40,743評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼刻撒,長吁一口氣:“原來是場噩夢啊……” “哼骨田!你這毒婦竟也來了?” 一聲冷哼從身側響起声怔,我...
    開封第一講書人閱讀 39,659評論 0 276
  • 序言:老撾萬榮一對情侶失蹤态贤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后醋火,有當地人在樹林里發(fā)現了一具尸體悠汽,經...
    沈念sama閱讀 46,200評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,282評論 3 340
  • 正文 我和宋清朗相戀三年胎撇,在試婚紗的時候發(fā)現自己被綠了介粘。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,424評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡晚树,死狀恐怖姻采,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情爵憎,我是刑警寧澤慨亲,帶...
    沈念sama閱讀 36,107評論 5 349
  • 正文 年R本政府宣布,位于F島的核電站宝鼓,受9級特大地震影響刑棵,放射性物質發(fā)生泄漏。R本人自食惡果不足惜愚铡,卻給世界環(huán)境...
    茶點故事閱讀 41,789評論 3 333
  • 文/蒙蒙 一蛉签、第九天 我趴在偏房一處隱蔽的房頂上張望胡陪。 院中可真熱鬧,春花似錦碍舍、人聲如沸柠座。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽妈经。三九已至,卻和暖如春捧书,著一層夾襖步出監(jiān)牢的瞬間吹泡,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評論 1 271
  • 我被黑心中介騙來泰國打工经瓷, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留爆哑,地道東北人。 一個月前我還...
    沈念sama閱讀 48,798評論 3 376
  • 正文 我出身青樓了嚎,卻偏偏與公主長得像泪漂,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子歪泳,可洞房花燭夜當晚...
    茶點故事閱讀 45,435評論 2 359

推薦閱讀更多精彩內容