Effective Java--讀書筆記
第2章 創建和銷毀對象
1.考慮用靜態工廠方法代替構造函數-->靜態工廠模式。
2.使用私有構造函數強化singleton屬性-->單例模式。
3.通過私有構造函數強化不可實例化的能力:
a.企圖通過將一個類做成抽象類來強制該類不可被實例化,是行不通的。
b.只要讓該類包含單個顯示的私有構造函數,則它就不可被實例化了。
4.避免創建重復的對象。
5.消除過期的對象引用。
6.避免使用finalizer函數。
內存泄漏問題:
如果一個棧顯示增長,然後再收縮,那麽,從棧中彈出來的對象將不會被當做垃圾回收,即使使用棧的客戶程序不再引用這些對象,它們也不會被回收。這是因為,棧內部維護著對這些對象的過期引用。
問題修復:
一旦對象引用過期,就清空這些引用。(比如 當一個單元被彈出棧,就把它的引用設置為null)。這樣的好處是,如果它們在以後又被錯誤地解除引用,則程序會立即拋出空指針異常,而不是悄悄地錯誤運行下去。
場景:
1.只要一個類自己管理它的內存。
2.緩存。
第3章 對於所有對象都通用的方法
7.在改寫equals的時候請遵守通用約定:
當一個類有自己特有的“邏輯相等”概念(而不是它們是否指向同一個對象),而且超類也沒有改寫equals以實現期望的行為,這時我們需要改寫它。
這通常適合於“值類”的情形,比如Integer或者Date。
通用約定:
a.自反性;對於任意的引用值x,x.equals(x)一定為true。
b.對稱性;對於任意的引用值x和y,並且僅當y.equals(x)返回true時,x.equals(y)也一定返回true。
c.傳遞性;對於任意的引用值x、y和z,如果x.equals(y)返回true,並且y.equals(z)也返回true,那麽x.equals(z)也一定返回true。
d.一致性;對於任意的引用值x和y,如果equals比較的對象信息沒有被修改的話,那麽,多次調用x.equals(y)要麽一致地返回true,要麽一致地返回false。
e.非空性;對於任意的非空引用值x,x.equals(null)一定返回false。
實現高質量equals方法的一個“處方”:
1.使用==操作符檢查“實參是否為指向對象的一個引用”;
2.使用instanceof操作符檢查“實參是否為正確的類型”;
3.把實參轉換到正確的類型;
4.對於該類中每一個“關鍵(significant)”域,檢查實參中的域與當前對象中對應的域值是否匹配。
5.當你編寫完後,檢查它是否對稱的、傳遞的、一致的。
8.改寫equals時總是要改寫hashCode相等的對象必須具有相等的hash碼。
9.總是要改寫toString。默認返回的是類名+@+16位進制的hash碼。
第6章 方法
23.檢查參數的有效性-->做校驗。
24.需要時使用保護性拷貝:
Java是安全的語言,對緩沖區溢出、數組越界、非法指針以及其他的內存破壞錯誤自動免疫。
25.謹慎設計方法的原型:
a.遵循標準的命令習慣。
b.不要過於追求提供便利的方法,只有一個操作被用得非常頻繁時候,才提供快捷方法。
c.避免長長的參數列表,三個視為實踐中的最大值。
d.對於參數類型,優先使用接口而不是類。例如,沒有理由在編寫一個方法時使用Hashtable作為輸入,相反,應該使用Map。這使得你可以傳入一個Hashtable、HashMap、TreeMap的子映射表。如果你使用一個類而不是一個接口,則限制了客戶只能傳入一個特定的實現。
e.謹慎地使用函數對象。
26.謹慎地使用重載:
永遠不要導出兩個具有相同參數數目的重載方法。
27.返回零長度的數值而不是null。
第7章 通用程序設計
31.如果要求精確的答案,避免使用float和double-->不適合用作貨幣計算。
33.了解字符串連接的性能:
使用StringBuffer的append方法。
34.通過接口引用對象
盡量這樣聲明:
List subs=new ArrayList();
而不是這樣的聲明:
ArrayList subs=new ArrayList();
如果沒有合適的接口存在的話,那麽,用類來引用一個對象,是合適的。
第8章 異常
40.對於可恢復的條件使用被檢查時異常,對於程序錯誤使用運行時異常。
46.努力使失敗保持原子性:
一個失敗的方法調用應該使對象保持“它在被調用之前的狀態”。
47.不要忽略異常:
catch塊也應該包含一條說明,用來解釋為什麽忽略掉這個異常是合適的。
第9章 線程
51.不要依賴於線程調度器(thread schcduler):
1.任何依賴於線程調度器而達到正確性或性能要求的程序,很有可能是不可移植的。
2.不要企圖通過調用Thread.yield來“修正”程序。
3.線程優先級是Java平臺上最不可移植的特征。
4.Thread.yield的唯一用途是在測試期間人為地增加一個程序並發性。
53.避免使用線程組。
第10章 序列化
54.謹慎地實現Serializable:
1.實現它的最大代價是,一旦一個類被發布,則“改變這個類的實現”的靈活性將大大降低。
2.第二個代價是,增加了bug和安全漏洞的可能性。
3.第三個代價是,隨著一個類的新版本的發行,相關的測試負擔增加了。
55.考慮使用自定義的序列化形式。
56.保護性地編寫readObject方法。
57.必要時提供一個readResolve方法。
Effective Java--讀書筆記