Effective Java Note (對(duì)象的創(chuàng)建和銷(xiāo)毀)

Effective Java Note (對(duì)象的創(chuàng)建和銷(xiāo)毀)

一雹姊、對(duì)象的創(chuàng)建和銷(xiāo)毀

1. 考慮使用靜態(tài)工廠方法替代構(gòu)造器

優(yōu)點(diǎn)

  1. 靜態(tài)工廠方法可以有一個(gè)名稱(chēng),易于理解與閱讀渠缕,工廠方法的名稱(chēng)可以凸顯出不同構(gòu)造器的區(qū)別
  2. 每次掉用的時(shí)候可以不用都創(chuàng)建一個(gè)新的對(duì)象仰楚,而是可以選擇復(fù)用對(duì)象,在一些情況就可以直接使用==判斷相等薛躬,而不是equals
  3. 可以返回原返回類(lèi)型的任意子類(lèi)型俯渤。可以參考java的集合框架型宝。使用接口來(lái)引用被返回的對(duì)象八匠,而不是通過(guò)實(shí)現(xiàn)類(lèi)來(lái)返回對(duì)象引用是一個(gè)好習(xí)慣。
  4. 在創(chuàng)建參數(shù)化類(lèi)型實(shí)例的時(shí)候代碼更簡(jiǎn)潔诡曙。例如通過(guò)類(lèi)型推倒與泛型:
public static <K,V> HashMap<K,V> newInstance(){
  return new HashMap<K,V>();
}

Map<String,List<String>> m = HashMap.newInstance();

缺點(diǎn)

  1. 如果類(lèi)不含有共有或者受保護(hù)的構(gòu)造器臀叙,那么將不能被子類(lèi)化。(可以通過(guò)組合化解)
  2. 與其他的靜態(tài)方法沒(méi)有實(shí)質(zhì)差別价卤。一個(gè)好的命名這時(shí)候就很重要了劝萤,讓人一看就知道是一個(gè)靜態(tài)方法的作用。

靜態(tài)工廠方法和構(gòu)建器對(duì)于有多個(gè)可選參數(shù)的時(shí)候慎璧,將增加復(fù)雜度與降低可讀性

2. 遇到多個(gè)構(gòu)造器參數(shù)時(shí)考慮使用構(gòu)建器

重疊構(gòu)造器在少數(shù)參數(shù)的時(shí)候可以床嫌,可以方便按需選擇構(gòu)造器,但是參數(shù)很多的時(shí)候胸私,很容易造成混亂厌处,閱讀型也會(huì)大大下降。有時(shí)候即使參數(shù)類(lèi)型是對(duì)的岁疼,但是最終結(jié)果也可能時(shí)錯(cuò)誤的阔涉。

此外基于JavaBeans思想可以使用 setXXX,為每個(gè)參數(shù)設(shè)置setter方法捷绒,這樣每個(gè)構(gòu)造參數(shù)都能很容易理解其作用瑰排,但是一個(gè)很?chē)?yán)重的缺點(diǎn)是:構(gòu)造的過(guò)程被分配到了幾個(gè)調(diào)用過(guò)程,容易造成不一致?tīng)顟B(tài)(尤其時(shí)多線(xiàn)程環(huán)境下)暖侨,而要保證一致?tīng)顟B(tài)需要付出很多精力去維護(hù)椭住。

構(gòu)建器一般是一個(gè)需要實(shí)例化的類(lèi)的靜態(tài)內(nèi)部類(lèi),提供了對(duì)參數(shù)的默認(rèn)設(shè)置字逗,同時(shí)對(duì)外可以提供鏈?zhǔn)秸{(diào)用進(jìn)行構(gòu)造京郑。例如:

Car car = new Car.Builder().name("benz").wheels(4).color(Color.BLACK).build();

而且在Builder的每個(gè)域中都可以進(jìn)行約束判斷,違反約束條件的情況可以跑出非法異常葫掉。Builder很好的結(jié)合了setter和重疊構(gòu)造器的優(yōu)點(diǎn)些举,參數(shù)數(shù)量可以更靈活,閱讀性更好

還可以考慮使用抽象工廠:

public interface Builder<T>{
  T build();
}

缺點(diǎn)

為了構(gòu)造一個(gè)實(shí)例需要多生成一個(gè)實(shí)例(Builder類(lèi))挖息。

3. 使用私有構(gòu)造器或者枚舉類(lèi)型強(qiáng)化單例(Singleton)

  1. 一個(gè)類(lèi)中之提供了一個(gè)私有的無(wú)參構(gòu)造器金拒,防止類(lèi)外進(jìn)行實(shí)例化。
public class CEO{
  public static final CEO INSTANCE  = new CEO();
  private CEO(){}
}

但是,無(wú)參私有構(gòu)造器可以通過(guò)反射的setAccessible()修改

解決這個(gè)問(wèn)題則需要在無(wú)參構(gòu)造器中加入判斷绪抛,當(dāng)進(jìn)行第二個(gè)實(shí)例化的時(shí)候拋出異常资铡。還以提供友好的getInstance()公共靜態(tài)方法。

如果該類(lèi)實(shí)現(xiàn)了序列化幢码,那么需要重寫(xiě)readResolve,防止反序列化時(shí)創(chuàng)建一個(gè)新的實(shí)例:

private Object readResolve(){
  return INSTANCE;
}

通過(guò)枚舉實(shí)現(xiàn)Singleton笤休,無(wú)償提供序列化機(jī)制,絕對(duì)防止多次實(shí)例化症副,簡(jiǎn)潔的同時(shí)功能和公有域很相似店雅。

public enum CEO{
  INSTANCE;
  public void speech(){....}
  public void work(){....}
}

工具類(lèi)中加入私有無(wú)參構(gòu)造器,防止實(shí)例化是個(gè)很好的習(xí)慣贞铣。

4. 避免不必要的對(duì)象創(chuàng)建

  1. 不要使用 new String("text");闹啦,這實(shí)際上創(chuàng)建了兩個(gè)實(shí)例。
  2. 能重用對(duì)象的時(shí)候盡量重用對(duì)象辕坝,但是需要避免重用對(duì)象造成的錯(cuò)誤窍奋,得不償失。
  3. 避免不必要的額自動(dòng)裝箱工作酱畅,能用原生類(lèi)型就用原生類(lèi)型琳袄。
  4. 慎重使用對(duì)象池,維護(hù)起來(lái)需要很多工作纺酸。

5. 消除過(guò)期的對(duì)象的引用

  1. 在一下設(shè)計(jì)的Stack出棧方法中:
public Object pop(){
  if(size==0)
    throw new EmptyStackExcetiop();
  return elements[--size];
}

經(jīng)過(guò)多次push增長(zhǎng)后窖逗,pop掉的元素依然在Stack中保持有過(guò)期引用并由Stack管理著,而這些過(guò)期引用后期不在被使用餐蔬,卻不能被垃圾回收器進(jìn)行回收碎紊。導(dǎo)致內(nèi)存泄露》担可以做一下修改:

public Object pop(){
  if(size==0)
    throw new EmptyStackExcetiop();
    Object o = elements[--size];
    element[size] = null;
  return o;
}

設(shè)計(jì)自己管理內(nèi)存的時(shí)候矮慕,都需要警惕內(nèi)存泄露帶來(lái)的問(wèn)題

  1. 緩存帶來(lái)內(nèi)存泄露可能是緩存引用不在使用但是仍然長(zhǎng)時(shí)間留在緩存中。
  • 當(dāng)設(shè)計(jì)的緩存項(xiàng)的生命周期由該鍵的外部引用決定時(shí)可以使用WeakHashMap
  • 可以使用Timer或者ScheduleThreadPoolExecutor設(shè)計(jì)一個(gè)后臺(tái)線(xiàn)程進(jìn)行引用清理工作
  • LinkedHashMap的removeEldsetEntry管理緩存啄骇,實(shí)現(xiàn)添加新緩存項(xiàng)的同時(shí)清除舊的緩存項(xiàng)
  1. 回調(diào)與監(jiān)聽(tīng)導(dǎo)致的內(nèi)存泄露是因?yàn)椋皇褂玫臅r(shí)候沒(méi)有顯示的取消注冊(cè)瘟斜,否則不斷的注冊(cè)回調(diào)或者監(jiān)聽(tīng)會(huì)不斷積累缸夹。可以只保存監(jiān)聽(tīng)的弱引用螺句。

6. 避免使用終結(jié)方法

  1. 避免盡量避免使用finalize()終結(jié)方法虽惭,因?yàn)閖vm不能保證何時(shí)執(zhí)行,或者是否執(zhí)行蛇尚,執(zhí)行需要多長(zhǎng)時(shí)間芽唇。
  2. 涉及資源釋放的的時(shí)候,盡可能的使用顯示終結(jié)方法,例如流操作中的close()方法匆笤,一般使用try..catch..finally研侣,并在finally中調(diào)用close()操作。
  3. 但是finalize方法可以作為最后的安全網(wǎng)操作炮捧,也就是在不顯示終結(jié)的時(shí)候提供最后的終結(jié)調(diào)用庶诡,長(zhǎng)時(shí)間釋放資源總比不釋放資源好∨乜危或者是用來(lái)釋放非關(guān)鍵本地自愿的額時(shí)候使用末誓。

子類(lèi)覆蓋了父類(lèi)的finalize方法,那么需要顯示調(diào)用父類(lèi)的finalize书蚪,super.finalize();

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末喇澡,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子殊校,更是在濱河造成了極大的恐慌晴玖,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,919評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件箩艺,死亡現(xiàn)場(chǎng)離奇詭異窜醉,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)艺谆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,567評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)榨惰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人静汤,你說(shuō)我怎么就攤上這事琅催。” “怎么了虫给?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,316評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵藤抡,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我抹估,道長(zhǎng)缠黍,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,294評(píng)論 1 292
  • 正文 為了忘掉前任药蜻,我火速辦了婚禮瓷式,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘语泽。我一直安慰自己贸典,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,318評(píng)論 6 390
  • 文/花漫 我一把揭開(kāi)白布踱卵。 她就那樣靜靜地躺著廊驼,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上妒挎,一...
    開(kāi)封第一講書(shū)人閱讀 51,245評(píng)論 1 299
  • 那天绳锅,我揣著相機(jī)與錄音,去河邊找鬼饥漫。 笑死榨呆,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的庸队。 我是一名探鬼主播积蜻,決...
    沈念sama閱讀 40,120評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼彻消!你這毒婦竟也來(lái)了竿拆?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,964評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤宾尚,失蹤者是張志新(化名)和其女友劉穎丙笋,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體煌贴,經(jīng)...
    沈念sama閱讀 45,376評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡御板,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,592評(píng)論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了牛郑。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片怠肋。...
    茶點(diǎn)故事閱讀 39,764評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖淹朋,靈堂內(nèi)的尸體忽然破棺而出笙各,到底是詐尸還是另有隱情,我是刑警寧澤础芍,帶...
    沈念sama閱讀 35,460評(píng)論 5 344
  • 正文 年R本政府宣布杈抢,位于F島的核電站,受9級(jí)特大地震影響仑性,放射性物質(zhì)發(fā)生泄漏惶楼。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,070評(píng)論 3 327
  • 文/蒙蒙 一诊杆、第九天 我趴在偏房一處隱蔽的房頂上張望鲫懒。 院中可真熱鬧,春花似錦刽辙、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,697評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春慨灭,著一層夾襖步出監(jiān)牢的瞬間朦乏,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,846評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工氧骤, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留呻疹,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,819評(píng)論 2 370
  • 正文 我出身青樓筹陵,卻偏偏與公主長(zhǎng)得像刽锤,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子朦佩,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,665評(píng)論 2 354

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

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法并思,類(lèi)相關(guān)的語(yǔ)法,內(nèi)部類(lèi)的語(yǔ)法语稠,繼承相關(guān)的語(yǔ)法宋彼,異常的語(yǔ)法,線(xiàn)程的語(yǔ)...
    子非魚(yú)_t_閱讀 31,625評(píng)論 18 399
  • 對(duì)象的創(chuàng)建與銷(xiāo)毀 Item 1: 使用static工廠方法仙畦,而不是構(gòu)造函數(shù)創(chuàng)建對(duì)象:僅僅是創(chuàng)建對(duì)象的方法输涕,并非Fa...
    孫小磊閱讀 1,981評(píng)論 0 3
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)慨畸,斷路器莱坎,智...
    卡卡羅2017閱讀 134,654評(píng)論 18 139
  • 午飯后拉張凳子坐在房里 讀著昨晚下載的無(wú)所意義自己愛(ài)的話(huà)題 看著看著睡過(guò)去了 帶著媽媽弟弟妹妹去了我的夢(mèng)里 醒來(lái)看...
    尼可呀閱讀 175評(píng)論 0 0
  • 若你身處的人群讓你感到焦慮型奥,忍不住回家挑剔自己,挑剔丈夫與孩子碉京,那么記得厢汹,你尚可以選擇告別他們。 很多年前谐宙,就意識(shí)...
    讀不白閱讀 391評(píng)論 0 1