第2章 創(chuàng)建和銷毀對象
后續(xù)補充例子.
第1條:考慮用靜態(tài)工廠方法代替構(gòu)造器
靜態(tài)工程方法與構(gòu)造器不同的優(yōu)勢:
- 有名稱, 表達更清楚, 更易于閱讀.
- 不必每次調(diào)用都返回對象. 能夠為重復(fù)的調(diào)用返回相同的對象, 極大地提升性能.
- 可以返回原返回類型的任何字類型的對象. 構(gòu)成服務(wù)提供者框架, 比如JDBC API.
- 在創(chuàng)建有參數(shù)的類型的實例的時候, 不用提供冗長的參數(shù). 這被稱作類型推導(dǎo).
靜態(tài)工廠方法的主要缺點:
- 類如果不含有公有的或者受保護的構(gòu)造器, 就不能被子類化.
但這樣也會因禍得福, 鼓勵使用組合, 而不是繼承. - 與其它靜態(tài)方法沒有任何區(qū)別:
將靜態(tài)工廠使用慣用名稱可以彌補. 比如:
valueOf
,of
,getInstance
,newInstance
,getType
,newType
.
第2條:遇到多個構(gòu)造器參數(shù)是要考慮用構(gòu)造器
靜態(tài)工廠方法和和構(gòu)造器的局限性: 不能很好地擴展到大量可選的參數(shù).
-
重疊構(gòu)造器模式
參數(shù)太多時, 代碼難以閱讀. -
JavaBean模式
類無法僅僅通過檢驗構(gòu)造器參數(shù)的有效性來保證一致性. -
Builder模式
容易編寫和閱讀, 可以有多個參數(shù), 使用靈活. 比重疊構(gòu)造器更加冗長, 因此只有在很多參數(shù)時才使用. 但是擴展性要強.
第3條: 用私有構(gòu)造器或者枚舉類型強化Singleton屬性
- 方法一:
把構(gòu)造器私有, 導(dǎo)出共有的靜態(tài)成員.
缺點是仍然可以通過反射機制調(diào)用私有構(gòu)造器. - 方法二:
公有成員是靜態(tài)工廠方法.
提供了靈活性; 與泛型有關(guān). - 方法三:
Java1.5之后, 使用枚舉類型.
無償?shù)靥峁┝诵蛄谢瘷C制.
第4條:通過私有構(gòu)造器強化不可實例化的能力
一些工具類沒有實例化的意義.
- 添加私有構(gòu)造器之后, 就不會調(diào)用缺省構(gòu)造器, 保證類不被實例化.
第5條:避免創(chuàng)建不必要的對象
- 使用靜態(tài)方法而不是構(gòu)造器, 以避免創(chuàng)建不必要的對象.
- 使用靜態(tài)初始化器
- 優(yōu)先使用基本類型而不是裝箱基本類型
第6條:消除過期的對象引用
內(nèi)存泄露問題
- 如果一個棧先增長, 然后再收縮, 那么從棧中彈出來的對象將不會被當(dāng)做垃圾回收, 即使使用棧的程序不再使用這些對象. 棧內(nèi)部維護著這些對象的過期引用.
只要類自己維護內(nèi)存, 就應(yīng)該警惕內(nèi)錯泄露問題. - 緩存引起內(nèi)存泄露.
- 監(jiān)聽器和其他回調(diào)引起內(nèi)存泄露.
解決方法是保存他們的弱引用, 比如WeakHashMap.
第7條:避免使用終結(jié)方法
finalize 通常是不可預(yù)測的, 也是很危險的, 一般情況下是不必要的.
- finalize 的缺點是不能保證被機制執(zhí)行. 會有非常嚴(yán)重的性能損失.
- 可以使用顯示的終止方法. 比如:I/O里的close()方法, 放在finally子句內(nèi)確保執(zhí)行.
- 使用finalize guardian.