【Effective JAVA】學習筆記

創建和銷燬對象

  1. 考慮用靜態工廠方法代替構造器
  2. 遇到多個構造器參數時,要考慮用構建器
    注:在lombok插件中 有個 @Builder註解 可以方便生成構建器,建造者模式
  3. 用私有構造器或者枚舉類型強化Singleton屬性
    注:可以參考單例的幾種實現方式,推薦枚舉 和 靜態類的方法實現,避免餓漢式加載和懶漢式的線程同步問題
  4. 通過私有構造器強化不可實例化的能力。
    注:對於一些工具類 建議加上私有構造器 避免無意義的實例化。
  5. 避免創建不必要的對象
  6. 消除過期的對象引用
    注:常見的導致內存泄漏的情況,a.棧的設計,出棧時未將當前棧位置空。b.緩存,c.監聽器的或其他回調,只註冊 不取消,可以嘗試使用軟引用 或者弱引用。
  7. 避免使用終結方法

對所有對象都通用的方法

  1. 覆蓋equals時請遵守通用約定
    注:自反性 x.equals(x) == true、對稱性、傳遞性、一致性
  2. 覆蓋equals時總要覆蓋hashCode
    注:equals相等,hashCode必須相等;但是hashCode相等,equals不一定相等
  3. 始終要覆蓋toString方法
    注:爲了輸出打印對象的可讀性,務必覆蓋toString對象
  4. 謹慎底覆蓋clone
    注:注意深拷貝和淺拷貝
  5. 考慮實現Comparable接口

類和接口

  1. 使類和成員的可訪問性最小化
    注:類的幾種訪問級別
  2. 在公有類中使用訪問方法而非公有域
  3. 使可變性最小化
    注:不可變對象儘量用final修飾 包括不可變屬性字段,本質上實現線程安全
  4. 複合優先於繼承
    注:封裝類 ,轉發類,裝飾模式的應用
  5. 要麼爲繼承而設計,並提供文檔說明,要麼就禁止繼承
  6. 接口由於抽象類
    注:多重組合繼承,通用的骨架實現類 如:AbstractSet
  7. 接口只用於定義類型
    注:接口導出常量屬於反面例子,以後避免使用,可以使用工具類替代
  8. 類層次由於標籤類
  9. 用函數對象表示策略
  10. 優先考慮靜態成員類

泛型

  1. 請不要在新代碼中使用原生態類型
  2. 消除非受檢警告
  3. 列表優先於數組
  4. 優先考慮泛型
  5. 優先考慮泛型方法
  6. 利用有限通配符來提升API的靈活性
  7. 優先考慮類型安全的異構容器

枚舉和註解

  1. 用enum代替int常量
  2. 用實例域代替序數
  3. 用EnumSet代替位域
  4. 用EnumMap代理序數索引
  5. 用接口模擬可伸縮的接口
    注:這個實現很妙,可以多參考借鑑
  6. 註解優於命名模式
    注:命名模式早已淘汰
  7. 堅持使用Overrider註解
  8. 用標記接口定義類型

方法

  1. 檢查參數的有效性
    注:assert斷言會拋出 AssertionError 異常,爲Error的子類。公有方法一般不用assert校驗
  2. 必要時進行拷貝性保護
    注:各層之間對象轉換 DTO,DOMAIN,DO,VO等,各域之間對象相互拷貝
  3. 謹慎設計方法簽名
  4. 慎用重載
  5. 慎用可變參數
  6. 返回零長度的數組或者集合,而不是null
  7. 爲所有導出的API元素編寫文檔註釋

通用程序設計

  1. 將局部變量的作用域最小化
  2. for-each循環優先於傳統的for循環
  3. 瞭解和使用類庫
  4. 如果需要精確的答案,請避免使用float和double
  5. 基本類型優先於裝箱基本類型
  6. 如果其他類型更合適,則儘量避免使用字符串
  7. 當心字符串鏈接的性能
  8. 通過接口引用對象
  9. 接口優先於反射機制
  10. 謹慎地使用本地方法
  11. 謹慎地進行優化
  12. 準守普遍接受的命名慣例

異常

  1. 只針對異常的情況才使用異常
  2. 對可恢復的情況使用受檢異常,對變成錯誤使用運行時異常
  3. 避免不必要地使用受檢的異常
  4. 優先使用標準的異常
    注:常見的標準異常有
    IllegalArgumentExcetion: 參數非法
    IllegalStateException: 狀態非法
    NullPointerExeption 禁止使用null的情況下 參數爲null
    ConcurrentModificationException 併發修改異常
    UnsupportedOperationException 不支持請求操作
  5. 拋出與抽象相對應的異常
  6. 每個方法拋出的異常都要有文檔
  7. 在細節消息中包含能捕獲失敗的信息
  8. 努力是失敗保持原子性
  9. 不要忽略異常

併發

  1. 同步訪問共享的可變數據
  2. 避免過度同步
  3. executor和task 優先於線程
  4. 併發工具優先於wait和notify
  5. 線程安全性的文檔化
  6. 慎用延遲初始化
  7. 不要依賴於線程調度器
    注:儘量確保可運行的線程數量不明顯多於CPU核數,否則資源競爭將嚴重降低性能
  8. 避免使用線程組

序列化

  1. 謹慎的實現Serializable接口
  2. 考慮使用自定義的序列化形式
  3. 保護性的編寫readObject方法
  4. 對於實例控制,枚舉類型優先於readResolve
  5. 考慮用序列化代理替代序列化實例
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章