創建和銷燬對象
- 考慮用靜態工廠方法代替構造器
- 遇到多個構造器參數時,要考慮用構建器
注:在lombok插件中 有個@Builder
註解 可以方便生成構建器,建造者模式 - 用私有構造器或者枚舉類型強化Singleton屬性
注:可以參考單例的幾種實現方式,推薦枚舉 和 靜態類的方法實現,避免餓漢式加載和懶漢式的線程同步問題 - 通過私有構造器強化不可實例化的能力。
注:對於一些工具類 建議加上私有構造器 避免無意義的實例化。 - 避免創建不必要的對象
- 消除過期的對象引用
注:常見的導致內存泄漏的情況,a.棧的設計,出棧時未將當前棧位置空。b.緩存,c.監聽器的或其他回調,只註冊 不取消,可以嘗試使用軟引用 或者弱引用。 - 避免使用終結方法
對所有對象都通用的方法
- 覆蓋equals時請遵守通用約定
注:自反性x.equals(x) == true
、對稱性、傳遞性、一致性 - 覆蓋equals時總要覆蓋hashCode
注:equals相等,hashCode必須相等;但是hashCode相等,equals不一定相等 - 始終要覆蓋toString方法
注:爲了輸出打印對象的可讀性,務必覆蓋toString對象 - 謹慎底覆蓋clone
注:注意深拷貝和淺拷貝 - 考慮實現Comparable接口
類和接口
- 使類和成員的可訪問性最小化
注:類的幾種訪問級別 - 在公有類中使用訪問方法而非公有域
- 使可變性最小化
注:不可變對象儘量用final修飾 包括不可變屬性字段,本質上實現線程安全 - 複合優先於繼承
注:封裝類 ,轉發類,裝飾模式的應用 - 要麼爲繼承而設計,並提供文檔說明,要麼就禁止繼承
- 接口由於抽象類
注:多重組合繼承,通用的骨架實現類 如:AbstractSet
等 - 接口只用於定義類型
注:接口導出常量屬於反面例子,以後避免使用,可以使用工具類替代 - 類層次由於標籤類
- 用函數對象表示策略
- 優先考慮靜態成員類
泛型
- 請不要在新代碼中使用原生態類型
- 消除非受檢警告
- 列表優先於數組
- 優先考慮泛型
- 優先考慮泛型方法
- 利用有限通配符來提升API的靈活性
- 優先考慮類型安全的異構容器
枚舉和註解
- 用enum代替int常量
- 用實例域代替序數
- 用EnumSet代替位域
- 用EnumMap代理序數索引
- 用接口模擬可伸縮的接口
注:這個實現很妙,可以多參考借鑑 - 註解優於命名模式
注:命名模式早已淘汰 - 堅持使用Overrider註解
- 用標記接口定義類型
方法
- 檢查參數的有效性
注:assert
斷言會拋出 AssertionError 異常,爲Error的子類。公有方法一般不用assert
校驗 - 必要時進行拷貝性保護
注:各層之間對象轉換 DTO,DOMAIN,DO,VO等,各域之間對象相互拷貝 - 謹慎設計方法簽名
- 慎用重載
- 慎用可變參數
- 返回零長度的數組或者集合,而不是null
- 爲所有導出的API元素編寫文檔註釋
通用程序設計
- 將局部變量的作用域最小化
- for-each循環優先於傳統的for循環
- 瞭解和使用類庫
- 如果需要精確的答案,請避免使用float和double
- 基本類型優先於裝箱基本類型
- 如果其他類型更合適,則儘量避免使用字符串
- 當心字符串鏈接的性能
- 通過接口引用對象
- 接口優先於反射機制
- 謹慎地使用本地方法
- 謹慎地進行優化
- 準守普遍接受的命名慣例
異常
- 只針對異常的情況才使用異常
- 對可恢復的情況使用受檢異常,對變成錯誤使用運行時異常
- 避免不必要地使用受檢的異常
- 優先使用標準的異常
注:常見的標準異常有
IllegalArgumentExcetion
: 參數非法
IllegalStateException
: 狀態非法
NullPointerExeption
禁止使用null的情況下 參數爲null
ConcurrentModificationException
併發修改異常
UnsupportedOperationException
不支持請求操作 - 拋出與抽象相對應的異常
- 每個方法拋出的異常都要有文檔
- 在細節消息中包含能捕獲失敗的信息
- 努力是失敗保持原子性
- 不要忽略異常
併發
- 同步訪問共享的可變數據
- 避免過度同步
- executor和task 優先於線程
- 併發工具優先於wait和notify
- 線程安全性的文檔化
- 慎用延遲初始化
- 不要依賴於線程調度器
注:儘量確保可運行的線程數量不明顯多於CPU核數,否則資源競爭將嚴重降低性能 - 避免使用線程組
序列化
- 謹慎的實現Serializable接口
- 考慮使用自定義的序列化形式
- 保護性的編寫readObject方法
- 對於實例控制,枚舉類型優先於readResolve
- 考慮用序列化代理替代序列化實例