第2章 創建和銷毀對象
第1條:考慮用靜態工廠方法代替構造器
靜態工廠方法,只是一個返回類的實例的靜態方法。
示例:boolean基本類型轉化成Boolean對象引用
public static Boolean valueOf(boolean e){
return b ? Boolean.TRUE : Boolean.FALSE;
}
優勢:
1.有名稱,也就是說看著清楚白。
2.不必在每次調用的時候都創建新的對象。(避免了創建不必要的重復對象,從而提高了性能)
重復的調用返回相同對象
實例受控的類:確保是單例,或者不可實例化,
使得不可變的類可以確保不會存在兩個相等的實例,當且僅當==時equals() 是true
3.可以返回原返回類型的任何子類型的對象。
4.在創建參數化類型實例的時候,使代碼變得更加簡潔。
構造器參數
Map<String,List<String>> map = new HashMap<String,List<String>>();
靜態方法---類型推導
Map<String,List<String>> map = HashMap.newInstance();
public static <K,V> HashMap<K,V> newInstance(){
return new HashMap<K,V>();
}
缺點:
1.類如果不包含公有或者受保護的構造器,就不能被子類化。
其實并不是什么缺點,鼓勵使用復用,而不是繼承。(16條)
2.與其他靜態方法實際上沒有任何區別。
但是有慣用的名稱:valueOf,of,newInstance,getInstance,getType,newType等
第2條:遇到多個構造器參數時要考慮用構建器
最容易想到的就是,重疊構造器模式。但是隨著參數增多,造成編寫困難,閱讀困難。
1.JavaBean模式 :調用默認的無參構造器創建對象,然后使用setter方法來設置每個參數(實踐中很少用)
當然有缺點:
構造過程JavaBean可能處于不一致的狀態。
JavaBean模式阻止了將該類做成不可變的可能。(15條)
2.Builder模式 24
此處有實例
如果類的構造器或者靜態工廠中具有多個參數,設計這種類時,Builder模式就是種不錯的選擇。
*** 第3條:用私有構造器或者枚舉類型強化Singleton屬性 ***
Singleton 指僅僅被實例化一次的類。
工廠方法的優勢:提供了靈活性;泛型
單元素的枚舉類型已經成為實現單例的最佳方法
public enum Elvis{
INSTANCE;
public void leaveTheBuilding(){……}
}
*** 第4條:通過私有構造器強化不可實例化的能力 ***
私有構造器,記得加注釋。
*** 第5條:避免創建不必要的對象 ***
最好能重用對象而不是每次需要的時候都創建一個相同功能的新對象。
如果對象是不可變的,它就始終可以被重用。
靜態的初始化器
static{
...
}
要優先使用基本類型而不是裝箱基本類型,要當心無意識的自動裝箱。
*** 第6條:消除過期的對象引用 ***
Stack類自己管理內存。存儲池包含了elements數組(對象引用單元,而不是對象本身)的元素。
數組活動區域的元素是已分配的,而數組其余部分的元素是自用的。但是GC不知道。
只要類是自己管理內存,就應該警惕內存泄露問題。
緩存:用WeakHashMap
LinkedHashMap是利用它的removeEldlestEntry方法實現
對于更復雜的緩存,使用 java.lang.ref
監聽器和其他回調
回調立即被當成gc :只保存他們的弱引用(weak reference),如保存成WeakHashMap的鍵
Heap剖析工具---Heap Profiler
*** 第7條:避免使用終結方法 ***
終結方法 (finalizer)
不應該依賴終結方法來更新重要的持久狀態。
System.gc 和 System。runFinalization 并不保證終結方法一定會被執行。
顯式的終止方法——一般與try-finally結構一起使用:
InputStream,OutputStream,sql的close()
Timer的cancel()
終結方法的好處:為了安全,與對象的本地對等體有關
將終結方法放到一個匿名的類里:終結它的外圍實例----終結方法守衛者
繼續補充中。。。