Android應用開發提高系列(1)——《Practical Java 中文版》讀書筆記(上)

書籍
  《Practical Java 中文版》  03版  侯捷、劉永丹譯  
  本書和《Effective Java》,對前述重要而基礎的技術細微處有著詳盡、深刻、實用的介紹、剖析和范例,又以獨立條款之姿展現,在內容的紮實度、可讀性及易讀性上的表現均十分良好。
  本書圍繞Java編程中遇到的實際問題展開。可以說書中所列專題正是那些令許多Java程序員困惑不已的FAQ。作者擅長采用恰如其分的示例來闡釋問題,以平時的語言娓娓道出中肯的建議。這些建議往往一語中的,能直接融入編程工作中,可見它們確實是出自作者從實踐中獲得的真知灼見。
 
正文
  註意:條目和用語可能與書籍有所出入,但盡量保持原樣加一些自己的理解。
  一、一般技術
    1.  Java唯一一種參數傳遞機制:by value(傳值)。
    備註:當參數為對象時,以傳值方式傳遞對象的引用。(個人理解:傳遞指針的拷貝)
 
    2.  對不變的data和object references使用final
    備註:當聲明一個對象為final時,不能改變其指向,但能改變其對象的值。
 
    3.  缺省情況下所有非私有(non-private)、非靜態(non-static)函數都可被覆寫。
      3.1  如果函數不想被子類覆寫,將函數聲明為final即可。
      3.2  如果類不想被子類覆寫,將類聲明為final即可,從而禁止覆寫該類所有函數。還能提高性能。
 
    4.  在數組和Vectors之間慎重選擇。
  數組 Vector
存儲數據類型 基本類型、引用類型 引用類型
元素默認值 Yes No
自動改變大小 固定不變 動態增長
速度快 Yes No
     備註: Vector內部實際是以數組實現的。
 
    5.  多態優於instanceof,必要時才使用instanceof。
    備註:例如從父類轉型為派生類時,需要使用instanceof。
 
    6.  一旦不需要的對象引用,就將它設為null。
    備註:如果局部變量的引用使用完離函數結束前還需要執行較大代碼,可在使用完後設置為null,以便或許能使其在垃圾回收器下次運行時被回收。
 
  二、 對象與相等性
    1.  區別  == 和 equals()
    備註:請使用 == 測試兩個基本類型是否完全相同,或測試兩個對象引用是否指向同一個對象;使用equals()比較兩個對象的內容是否相等。
 
    2.  不要依賴equals()缺省實現
    備註:所有Java對象都隱含繼承瞭java.lang.Object,默認的equals()隻是檢查對象引用是否指向同一個對象。
 
    3.  實現equals()建議:
      3.1  請檢查是否等於this
        備註:測試是否指向同一個對象
      3.2  優先考慮使用getClass()
        備註:getClass()返回某個對象的運行期類(runtime class)。確保隻有相同class所產生的對象才有機會被視為相等。范例:
 
    public class Base {

        @Override
        public boolean equals(Object obj) {
            if(obj != null && getClass() == obj.getClass()){
                //繼續比較相等性或直接返回true
            }
            return false;
        }
    }
 
      3.3  調用super.equals()喚起父類的相關行為
        備註:當你為一個派生類撰寫equals()時,你必須檢查除java.lang.Object之外所有父類,看看它們是否都實現瞭equals()。如果有,那麼一定要調用super.equals()。
      3.4  在equals()函數中謹慎使用instanceof
        備註:如果允許派生類和父類進行比較,可能要采用instanceof(getClass()會恒返回false)。註意instanceof類似於is-a語義,需要註意位置,即(子類 instanceof 父類 -> 返回true;反之為false)。
 
  三、 異常處理
    1.  認識異常流程機制
      備註:try區段 -> [catch捕獲區段][可選] -> finally終結區段。
 
    2.  處理異常
      如果異常產生卻未被捕獲,發生異常的線程將中斷。處理異常:
      a). 捕獲並處理它,防止進一步傳播。
      b). 捕獲並拋出一個新的異常給調用端。
        備註:應確保新拋出的異常包含原異常相關信息,以保證不丟失重要信息。
      c). 不捕獲,任其傳播給調用端。
      輸出錯誤信息:
      a). 日志文件記錄曾經發生過的異常
      b). 輸出異常
        輸出到標準錯誤串流:如e.printStackTrace()。
 
    3.  防止出現異常覆蓋
      備註:如果在catch或finally區段又拋出瞭未捕獲的異常,新的異常將覆蓋try拋出的異常,隻有一個異常可被傳播到調用段。
 
    4.  throws子句
      備註:提供throws子句的用意在於,提醒函數調用者,告知可能發生的異常。編譯器會強迫調用端捕捉這些被列出的異常,所以不要再開發周期的最後才添加。
        如果覆寫對象(某個父類函數)沒有拋出任何異常,那麼覆寫函數因為增加瞭代碼而引發異常,那麼你必須在新函數中捕捉異常並處理。
 
    5.  使用finally避免資源泄漏
      備註:finally區段代碼無論是否發生異常都將執行,尤其適合維護對象內部狀態和清理non-memory資源。
 
    6.  使用建議:
      a). 不要從try區段執行return、break或continue語句離開try區段
        備註:如果try區段和finally區段都return 數據,將返回finally區段return的數據。
      b). 將try/catch區段置於循環之外
        備註:異常對代碼性能產生負面影響
      c). 不要將異常用於流程控制
      d). 在構造函數中拋出異常
      e). 拋出異常之前將對象恢復為有效狀態
        備註:考慮下次執行這段代碼時會發生什麼事情,代碼是否還能正常運行。
 
結束
  預計本系列前幾篇文章為《Practical Java》和《Effective Java》的讀書筆記,後續內容還在規劃當中,也歡迎大傢把感興趣的內容反饋給我作為潛在的系列文章。

 

摘自 農民伯伯

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *