effective java(第三版)---讀書筆記
第一章 引言
《 Effective Java》這本書并不厚,而且并不适合初學者,适合有一定的工作經驗的java攻城獅。這本書不是百科全書式的JAVA 手冊,而是試圖在講述如何正确、高效地使用java這門語言來完成日常的開發工作。
如今(2019)java已經誕生了24個年頭,在這些年裡,java被廣泛應用在許多領域,并且開發者、類庫以及生态環境也在不斷壯大。這本書的作者是一名知名的java專家,曾在sun公司以及google任職,上司開發了很多專業的java類庫。
本書的第一版誕生于2001年,那個時候java這門語言才剛剛誕生不久。本書的第二版則誕生于2008年,那個時候java5/6剛剛誕生,引入了很多新的特性,比如泛型、for-each循環等,本書的第三版則誕生于2017年,與時俱進地增加了很多新内容,特别是關于java7/8/9的新特性,比如lambda表達式,optional,stream,module等。而且作者列出的建議條目也從原來的70多個增加到90個,同時也删改了一些過時的内容。
總體來說,這仍然是java程式員案頭必備的一本JAVA最佳實踐參考書,值得經常拿出來翻一番,對于提高編碼的思想與技術一定會大有裨益。
第二章 建立和銷毀對象
建議1:使用靜态工廠函數替代公有的構造器。
公有的構造器的主要缺點是:一般隻能有一個共有的構造函數,如果想有多個構造函數,就要傳入不同數量的參數。但是這種情況下的多個構造器容易語義不明,讓調用者感到困惑。
靜态工廠方法有以下幾個好處:
- 有名稱,數量沒有限制,易于閱讀。
- 友善建構一個singleton,節約建立對象的開銷。
- 可以傳回原類型的任何類型的子類型對象。
- 傳回的對象可以随着每次調用而發生變化,這取決于靜态工廠方法的參數值。
- (hard) 方法傳回對象所屬的類,在編寫包含該靜态工廠方法的類時可以不存在。
靜态工廠方法的主要缺點:
- 如果類不包含公有的或者受保護的構造器,那麼就無法被子類化。但是這麼做也許會帶來額外的好處,那就是
鼓勵多用複合而不是繼承。
- 程式員比較難以發現這些靜态工廠函數,但是這點一般可以通過标準注釋以及習慣命名來解決,靜态工廠函數一般有如下的習慣名稱:
from
valueof
instance / getInstance
create / newInstance
getType
newType
type
建議2:遇到很多個構造器參數時,要考慮使用建構器(builder)
比如一個類有10個field,而且有着不同個數參數的初始化方式,比如有的時候需要傳遞3個參數,而有的時候則需要傳遞10個參數。一般的做法是,分别寫有不同個數的構造器,然後按照需求調用。但是這種方式往往很難搞懂到底該怎麼傳參數,因為沒有名稱,而且如果兩個類型相同但是順序不同的參數放到一起,傳入順序如果搞反了,這種錯誤是很難及時發現的。
是以為了解決這個問題,一般可以使用JavaBean 模式,也就是編寫很多setXXX方法,分别用于傳遞不同的參數,這種方法的好處是傳參清晰易懂,但是有一個緻命的缺點,那就是構造的過程中,類可能處于不一緻的狀态,而且也沒有辦法驗證構造器參數的有效性(可能遺漏了某個set方法)。
這種情況下的最佳解決辦法,是使用建構器,即builder 模式。主要的方法是建立一個靜态公有内部類Builder,其field 與原始類的field保持一緻,如果是必傳參數,則是 final類型,而且提供一個共有的Builder構造函數來傳入這些必傳參數,然後可選參數則通過一系列傳回值是Builder對象本身的函數來實作,這樣可以實作流式調用。最後提供一個build函數來傳回構造好的原對象,提供一個私有的,傳入參數為 Builder對象的原始類構造函數,來實作build 函數。
總體上來說,builder模式在有很多個構造器參數時,既可以讓傳入的參數具名,又可以避免遺漏某個傳入參數導緻構造對象不一緻的情況發生(可以在Builder内部檢查傳入參數的有效性)。
但是builder模式也有其缺陷:
- 為了建立對象,必須要建立其構造器,等于要建立兩個對象,這在對性能有嚴格要求的場景下可能會有問題,不過大部分情況下可以忽略不計。
- builder 模式寫起來比較麻煩、冗長。
但是其優點也是顯著的,一旦一開始使用builder模式,當後面需要擴充參數時,非常友善,隻需要在Builder内部增加相應的函數即可,擴充性非常好,而且非常易讀,且安全。
熱愛程式設計,熱愛機器學習!
github:http://www.github.com/Lyrichu
github blog:http://Lyrichu.github.io
個人部落格站點:http://www.movieb2b.com(不再維護)