1. 程式人生 > >Effective Java--讀書筆記

Effective Java--讀書筆記

以及 聲明 AR hashtable ceo 不可 溢出 必須 AD

第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--讀書筆記