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

學(xué)習(xí)目的:

  1. 何時(shí)以及如何創(chuàng)建對象
  2. 何時(shí)以及如何避免創(chuàng)建對象
  3. 如何確保對象適時(shí)銷毀
  4. 如何管理對象銷毀前必須進(jìn)行的各種清理動作

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

該靜態(tài)工廠方法不同于設(shè)計(jì)模式中的工廠方法,主要用于如何鮮明提供可定制化的實(shí)例構(gòu)造方法。

優(yōu)勢:
    1. 靜態(tài)方法可以提供名稱,可以確切地描述返回的對象,更易于代碼閱讀、理解。
    2. 不必每次調(diào)用的時(shí)候都創(chuàng)建新的對象,這樣就可以反復(fù)使用預(yù)先構(gòu)建好的對象,或者將創(chuàng)建的對象緩存起來,有利于提升性能,這種方式在單例模式中應(yīng)用較多。
    3. 通過依賴于接口,而不依賴與具體實(shí)現(xiàn),可以靈活返回實(shí)現(xiàn)該接口的子類。
    4. 構(gòu)造參數(shù)化實(shí)例時(shí),代碼更加簡潔。
  劣勢:
    要提供可在外部實(shí)例化的類,否則優(yōu)勢3無法體現(xiàn),而已靜態(tài)工廠方法依然只是一個(gè)普通的靜態(tài)方法,需要提供注釋來表示她的構(gòu)造功能說明。

針對劣勢方面,可以提供通用的方法名稱如valueOf,newInstance,getInstance等來標(biāo)示該方法的存在意義。更主要的是在構(gòu)建對象時(shí)考慮需不需要通過靜態(tài)工廠來靈活構(gòu)造實(shí)例對象。

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

在實(shí)例化某些對象時(shí),可能需要提供多個(gè)參數(shù),而有些參數(shù)是必須的或可選的,這個(gè)時(shí)候一般就會提供多個(gè)構(gòu)造器來實(shí)例化不同的對象。

  • 對象的實(shí)例化參數(shù)增多,意味著構(gòu)造方法也同時(shí)增多,代碼的可讀性也隨之下降。
  • 采取builder模式,完全由Builder來靈活定制對象的實(shí)例屬性,針對每個(gè)屬性提供一個(gè)set方法即可。
  • 調(diào)用build方法來構(gòu)建對象,并在對象構(gòu)建方法中即可一次性檢測參數(shù)設(shè)置異常

3. 用私有構(gòu)造器或枚舉來強(qiáng)化Singleton模式

  1. 對于實(shí)現(xiàn)Singleton模式一般都需要將構(gòu)造器私有化,但通過Java的反射方式依然能破壞該模式,可以通過修改私有構(gòu)造器在實(shí)例化第二個(gè)對象時(shí)直接拋出異常來保證單例不被破壞。
  2. 對象的序列化和反序列號也能破壞單例模式,需要提供readResolve方法來保證返回實(shí)例相同。
  3. 單元素枚舉方式來保證Singleton模式,自動提供上述兩種功能,并且能保證線程安全,是目前Singleton最佳方法。

4. 通過私有構(gòu)造器來強(qiáng)化不可實(shí)例化的能力

有時(shí)候需要編寫一個(gè)只需要包含靜態(tài)方法或靜態(tài)域的類,用于提供一些工具性的方法,而這樣的工具類一般不希望被實(shí)例化。

在編寫類時(shí)若不提供構(gòu)造方法,則系統(tǒng)會自動生成一個(gè)無參構(gòu)造器,所以我們需要編寫一個(gè)私有構(gòu)造器,并在內(nèi)部直接拋出異常,你也可以在上面編寫注釋表明意圖。

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

what:
  不必要的對象的鮮明特征就是對于反復(fù)使用的某一功能或方法,在每次運(yùn)行時(shí)都會重新創(chuàng)建對象,而不是使用之前已有對象。
why:
  對象的創(chuàng)建是需要代價(jià)的,大量創(chuàng)建無用對象既增加占用內(nèi)存也減少了代碼運(yùn)行流暢,比如創(chuàng)建數(shù)據(jù)庫連接對象需要較大開銷,如果能復(fù)用之前已有連接對象,對于提升性能具有顯著幫助。
how:
  可以考慮在將常用對象緩存住,比如靜態(tài)域等等。但是不要總是考慮緩存對象這樣不一定能提升能力,只是對于一些創(chuàng)建對象開銷較大并且使用較多對象緩存,創(chuàng)建一些微對象對于代碼運(yùn)行并沒有多少影響。

6. 消除過期的對象引用

Java是能夠自動進(jìn)行垃圾回收但前提是對象沒有被引用,而在代碼編寫過程中由于緩存或一些其他使用導(dǎo)致在不需要該對象時(shí),依然內(nèi)部持有該對象的引用,導(dǎo)致該對象沒有被及時(shí)釋放,從而導(dǎo)致內(nèi)存泄漏。所以對不再需要使用的對象盡量置為null或者對于一些對象采用弱引用。

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

首先終結(jié)方法是JVM自己調(diào)用的,而隨著垃圾回收算法改變,終結(jié)算法調(diào)用時(shí)刻也是不一致的,所以不要依賴終結(jié)方法做一些額外的操作,這樣會導(dǎo)致整個(gè)應(yīng)用崩潰的,而且Java并不提供能直接命令系統(tǒng)進(jìn)行垃圾回收的方法,System.gc()也只是建議開始系統(tǒng)回收的。
  如果顯示覆蓋終結(jié)方法,來一定要調(diào)用父類終結(jié)方法,因?yàn)镴VM不會主動調(diào)用父類的gc方法的。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容