《Effect Java》 概括總結

目錄:
1、建立和銷燬對象 (1 ~ 7)
2、對於全部對象都通用的方法 (8 ~ 12)
3、類和接口 (13 ~ 22)
4、泛型 (23 ~ 29)
5、枚舉和註解 (30 ~ 37)
6、方法 (38 ~ 44)
7、通用程序設計 (45 ~ 56)
8、異常 (57 ~ 65)
9、併發 (66 ~ 73)
10、序列化 (74 ~ 78)
 
正文:
 
第一章: 建立和銷燬對象
一、考慮用靜態工廠方法代替構造器
優:
① 有名稱
② 沒必要在每次調用它們的時候都建立一個對象
③ 能夠放回原返回類型的任何子類型的對象
④ 在建立參數化類型實例的時候,代碼更簡潔
缺:
① 類若是不含公有的或受保護的構造器,就不能被子類化
② 與其餘通常的靜態方法無多大區別
二、 遇到多個構造器參數時要考慮用構造器
三、用私有構造器或者枚舉類型強化 Singleton 屬性
四、經過私有構造器強化不可實例化的能力
五、避免建立沒必要要的對象
六、消除過時的對象引用
七、避免使用終結方法
 
第二章: 對於全部對象都通用的方法
八、覆蓋 equals 時請遵照通用約定
① 類的每一個實例本質上是惟一的
② 不關心類是否提供了「邏輯相等」的測試功能
③ 超類已經覆蓋了 equals, 從超類繼承過來的行爲對於子類也是合適的
④ 類是私有的或包級私有的,能夠肯定它的 equals 方法永遠不會被調用
 
   實現高質量 equals 方法訣竅:
① 使用 「==」操做符檢查「參數是否爲這個對象的引用」
② 使用 instanceof 操做符檢查「參數是否爲正確的類型」
③ 把參數轉換爲正確的類型
④ 對於該類中的每一個「關鍵」域,檢查參數中的域是否參與該對象中的對應的域相匹配
⑤ 當你編寫完成了 equals 方法以後,應該判斷其是否知足了 對稱性、傳遞性、一致性
      • 覆蓋 equals 時總要覆蓋 hashCode
      • 不要企圖讓 equals 方法過於智能
      • 不要將 equals 聲明中的 Object 對象器替換爲其餘的類型
九、覆蓋 equals 時總要覆蓋 hashCode
十、始終要覆蓋 toString
十一、謹慎地覆蓋 clone
十二、考慮實現 Comparable 接口
 
第三章:類和接口
1三、使類和成員的可訪問性最小化
1四、在公有類中使用訪問方法而非公有域
1五、使可變性最小化
① 不要提供任何會修改對象狀態的方法
② 保證類不會被擴展
③ 使全部的域都是 final 的
④ 使全部的域都成爲私有的
⑤ 確保對於任何可變組件的互斥訪問
1六、複合優先於繼承
  簡而言之,繼承的功能很是強大,可是也存在諸多問題,由於它違背了封裝原則。只有當子類和超類之間確實存在子類類型關係時,使用繼承纔是恰當的。即使如此,若是子類和超類處在不一樣的包中,而且超類並非爲了繼承而設計的,那麼繼承將會致使脆弱性。爲了不,能夠用複合和轉發機制來代替繼承,尤爲是當存在適合的接口能夠實現包裝類的時候。包裝類不只比子類更加健壯,並且功能也更增強大。
1七、要麼爲繼承而設計,並提供文檔說明,要麼就禁止繼承
1八、接口優於抽象類
① 現有的類能夠很容易被更新,以實現新的接口
② 接口的定義的理想選擇
③ 接口容許咱們構造非層次結構的類型框架
  接口一般是定義容許多個實現的類型的最佳途徑。這條規律有個例外,即當演變的容易性比靈活性和功能更爲重要的時候。在這種狀況下,應該使用抽象類來定義類型,但前提是必須理解而且能夠接受這些侷限性。若是你導出了一個重要的接口,就應該堅定考慮同時提供骨架實現類。最後,應該儘量謹慎的設計全部的公有接口,並經過編寫多個實現類對它們進行全面的測試。
1九、接口只用於定義類型
    接口應該只被用來定義類型,它們不該該被用來導出常量。
20、類層次優於標籤類
  標籤類不多有適用的時候。當你想要編寫一個包含顯示標籤域的類時,應該考慮一下,這個標籤是否能夠被取消,這個類是否能夠用類層次來代替。當你遇到一個包含標籤域的現有類時,就要考慮將它重構到一個層次結構中去。
2一、用函數對象表示策略
  要聲明一個接口來表示該策略,而且爲每一個具體策略聲明一個實現了該接口的類。當一個具體策略只被使用一次時,一般實現匿名類來聲明和實例化這個具體策略類。當一個具體策略類是設計用來重複使用的時候,它的類一般就要被實現爲私有的靜態成員類,並經過公有的靜態 final 域被導出,其類型爲該策略接口。
2二、優先考慮靜態成員類
  靜態成員類、非靜態成員類、匿名類、局部類
① 若是一個嵌套類須要在單個方法以外仍然是可見的,或者他太長了,不適合於放在內部,就應該使用成員類。
② 若是成員類的每一個實例都須要一個指向其外圍實例的引用,就要把成員類作成非靜態的;不然就作成靜態的。
③ 假設這個嵌套類屬於一個方法的內部,若是你只須要在一個地方建立實例,而且已經有一個預置的類型能夠說明這個類的特徵,就要把它作成匿名類;不然,就作成局部類。
 
第四章 泛型
2三、請不要在新代碼中使用原生態類型
2四、消除非受檢警告
  每一條警告都表示可能在運行時片拋出 ClassCastException 異常。要盡最大的努力消除這些警告。若是沒法消除非受檢警告,同時能夠證實引發警告的代碼是類型安全的,就能夠在儘量小的範圍中,用 @SuppressWarnings("unchecked")註釋禁止該警告。要用註釋把禁止該警告的緣由記錄下來。
2五、列表優先於數組
    數組和泛型有着很是不一樣的類型規則。數組是協變且能夠具體化的;泛型是不可變的且能夠被擦除的。所以數組提供了運行時的類型安全,當時沒有編譯時的類型安全,反之,對於泛型也同樣。通常來講,數組和泛型不能很好地混合使用。若是你發現本身將它們混合起來使用,而且獲得了編譯時錯誤或警告,應該用列表代替數組。
2六、優先考慮泛型
2七、優先考慮泛型方法
2八、利用有限制通配符來提高API 的靈活性
2九、優先考慮類型安全的異構容器
 
第六章 枚舉和註解
30、用 enum 代替 int 常量
3一、用實例域代替序數
3二、用 EnumSet 代替位域
3三、用 EnumMap 代替序數索引
3四、用接口模擬可伸縮的枚舉
3五、註解優先於命名模式
3六、堅持使用 Override 註解
3七、用標記接口定義類型
 
第七章 方法
3八、檢查參數的有效性
3九、必要時進行保護性拷貝
40、謹慎設計方法簽名
   ① 謹慎地選擇方法的名稱
  ② 不要過於追求提供便利的方法
  ③ 避免過長的參數列表
4一、慎用重載
  「可以重載方法」並不意味着就「應該重載方法」。通常狀況下,對於多個具備相同參數數目的方法來講,應該儘可能避免重載方法。在某些狀況下,特別是涉及構造器的時候,要遵循這條建議也許是不可能的。在這種狀況下,至少應該避免這樣的情形:同一組參數只需通過類型轉換就能夠被傳遞給不一樣的重載方法。
4二、慎用可變參數
4三、返回零長度的數組或者集合,而不是 null
4四、未全部導出的 API 元素編寫文檔註釋
 
第八章 通用程序設計
4五、將局部變量的做用域最小化
4六、for-each 循環優先於傳統的 for 循環(除了 在過濾、轉換、平行迭代下外)
4七、瞭解和使用類庫
4八、若是須要精確的答案,請避免使用 float 和 double
4九、基本類型優先於裝箱基本類型
50、若是其餘類型更適合,則儘可能避免使用字符串
  ① 字符串不適合代替其餘的值類型
  ② 字符串不適合代替枚舉類型
  ③ 字符串不適合代替彙集類型
  ④ 字符串不適合代替能力表
5一、小心字符串鏈接的性能
5二、經過接口引用對象
5三、接口優先於反射機制
  反射的不足:
    ① 喪失了編譯時類型檢查的好處
    ② 執行反射訪問所須要的代碼很是笨拙和冗長
    ③ 性能損失
5四、謹慎使用本地方法
5五、謹慎地進行優化
5六、遵照廣泛接受的命名慣例
 
第九章 異常
5七、只針對異常的狀況才使用異常
5八、對於可恢復的狀況使用受檢異常,對於編程錯誤使用運行時異常
5九、避免沒必要要地使用受檢的異常
60、優先使用標準的異常
6一、拋出與抽象相對應的異常
6二、每一個方法拋出的異常都要有文檔
6三、在細節消息中包含能捕獲失敗的信息
6四、努力使失敗保持原子性
6五、不要忽略異常
 
第十章 併發
6六、同步訪問共享的可變數據
6七、避免過分同步
  爲了不死鎖和數據破壞,千萬不要從同步區域內部調用外來方法。更爲通常地講,要儘可能限制同步區域內部的工做量。   
6八、executor 和 task 優先於線程
6九、併發工具優先於 wait 和 notify
70、線程安全性的文檔化
7一、使用延遲初始化
7二、不要依賴於線程調度器
7三、避免使用線程組
 
第十一章 序列化
7四、謹慎地實現 Serializable 接口
   使用此接口代價:
    ① 一旦一個雷被髮布,就大大下降了「改變這個類的實現」的靈活性
    ② 增長了出現 Bug和安全漏洞的可能性
    ③ 隨着類發行新的版本,相關的測試負擔也增長了   
7五、考慮使用自定義的序列化形式
  使用默認序列化形式缺點:
    ① 它使這個類的導出 API 永遠地束縛在該類的內部表示法上
    ② 它會消耗過多的空間
    ③ 它會消耗過多的時間
    ④ 它會引發棧溢出
7六、保護性地編寫 readObject 方法
7七、對於實例控制,枚舉類型優先於 readResolve
7八、考慮用序列化代理代替序列化實例
相關文章
相關標籤/搜索