天天看點

《practical Java》讀書筆記概述:

題記:

花了一周把Peter Haggar的《practical Java》看了遍,有所感悟,年紀大了, 寫下筆記,友善日後檢視.也希望有緣之人可以看看,做個渺小的指路人。 不足之處還望指正。
全書分為六個部分,包括一般技術、對象與相等性、異常處理、性能、多線程、對象。

一般技術:舉例了幾個java常見錯誤用法的說明和解釋,諸如array和vector的選擇,多态與instanceof等等

對象和相等性則:針對equals的詳細說明,是迄今本人見過對equals了解最深的一本書了,其中不乏java的一些規範

異常處理:主要介紹了java異常機制的使用細節,其中有一點就是return後的邏輯一律不執行在try finally模式裡頭是無效的

性能:介紹了java常用的一些優化細節,諸如使用棧變量來代替堆變量,減少同步化,使用arraycopy方法來代替自己的循環複制數組等等

多線程:簡要的說明了java線程使用中一些常見的知識點,如果對java多線程有興趣的,可以看看《Java并發程式設計實戰》

對象:介紹了接口與繼承的關系與使用,對深入學習java架構源碼有一定的幫助,感興趣的可以多思考下其中的奧義

正題中将挑選自己覺得比較有用的一些知識點進行說明,但并不代表其他知識點就不重要(因人而異,盡信書 不如無書)

最後我會将代碼工程打包好,感興趣的可以去下載下傳下來看看。

實踐1:參數以by value 方式而非by reference 方式傳遞

《practical Java》讀書筆記概述:
《practical Java》讀書筆記概述:

View Code

實踐2、3:final的用法 略

實踐4:在arrays和vectors之間慎重選擇

數組在java中使用率遠遠超過vector,是以這裡就要明白何時應該使用vector

首先vector是線程安全的,這樣就保證了他可以同步控制對象,

其次vector内部實作也是數組,隻不過是泛型對象的數組(數組更多時候存儲的是基礎類型)

最後就是數組的大小是無法自行拓展的,而vector是可以通過System.arraycopy()方法進行複制擴充vector的容量

實踐5:多态優于instanceof

這裡必須明白java多态和instanceof用法,簡單說下兩者的概念

所謂的多态就是不同對象對同一個消息作出不同的響應,java中的多态包含了重載和重寫(覆寫)

instanceof 運算符是用來在運作時指出對象是否是特定類的一個執行個體,通過傳回一個布爾值來指出,這個對象是否是這個特定類或者是它的子類的一個

先看下面一個例子

上面例子中 程式員在計算工資的時候是需要考慮獎金的,是以通過Instanceof來判定傳給

calcSalary方法的參數是否是Programmer類,如果是

則在原有工資計算方法上加上bonus()方法

表面上看,這樣的邏輯沒有問題,但是我們是需要考慮拓展的,加入現在還有産品經理,他的工資也有獎金

另外還有其他福利,在加上其他崗位

那麼每增加一個崗位的變動

我們都需要去修改calcSalary方法,而這樣的設計明顯是不符合java的規範的

書本作者給出的方案是讓經理也有獎金的方法,這不過這個獎金是0

進而避免了instanceof的産生,具體做法看書本,此處略

實踐6:必要時才需要instanceof

java支援父類向下轉型,即使是錯誤的向下轉型

在編譯的時候是不會報錯的,是以容易讓開發人員帶來幹擾

實踐7:一旦不再需要object reference,就将它設為null

接觸java的都明白java自帶的虛拟機有垃圾回收機制,不願太操心記憶體問題,其實作為一名合格的javaer也是需要考慮記憶體洩露的

況且java确實有存在,當然這裡不再我們的讨論話題中,為什麼沒用的引用盡量要手動的去觸發unusefulObj=null呢

其實就是減輕JVM的工作量,gc不是随時觸發的 這個應該要懂得

執行個體中的例子已經很不錯了

《practical Java》讀書筆記概述:
《practical Java》讀書筆記概述:

實踐8:差別reference類别和primitive型别

這個可能比較拗口很難了解字面的意思,其實也是實踐1所說的基礎類型和對象引用之間的差別

這裡主要是介紹下java1.5的一個新特性:拆箱和裝箱

Integer i1=100;//等同于new Integer(100)  這裡就是一個自動裝箱的過程

int k=i1;// 自動拆箱的過程  

更多關于拆箱與裝箱

可以移步http://www.cnblogs.com/danne823/archive/2011/04/22/2025332.html

關于包裝類的緩存:http://blog.csdn.net/yaoweijq/article/details/6021706

實踐9:區分==和equals

這個是java經常碰到的一個基礎知識點,即"=="和"equals"差別,何時使用==何時使用equals

總結起來可以這麼說:== 對于基礎類型 比較的是vlaue,而引用類型比較的是位址,當對象不需要單純的比較位址

而需要你自己DIY的時候,請重寫equals方法吧

至于何時使用,可以這麼說:==經常是基礎類型在用,引用類型的基本不用

equals最常見,而且多數情況下你是需要重寫的

有點以偏概全,希望拍磚

實踐10:不要依賴equals()的預設實作

不啰嗦了,直接上代碼

《practical Java》讀書筆記概述:
《practical Java》讀書筆記概述:

上面算是比較正常的一個重寫equals的方法,後續書本作者也提到了一個情況

就是對象的變量如果不是基礎類型,也是引用類型的話,就需要額外處理了(舉個例子,比如brand改成Stringbuffer類型)

作者給出了四個解決辦法:

1.不使用Stringbuffer,繼續使用String 2.比較的時候 先将Stringbuffer對象轉出String(調用toString()方法) 3.繼承Stringbuffer,重寫equals方法 讓變量變成重寫類的類型(有點拗口) 4.放棄equals改用compare()方法

例子書本上都有,感興趣的都可以去看看

關于何時重寫equals,上一節已經表述了自己的觀點,這裡補充下原作者的觀點:

《practical Java》讀書筆記概述:

實踐11~15 略  

實踐16:認識【異常控制流】機制

記住一個模式:try { //do something }catch(Exception e){// when exception happen

 to do }finally{//不管有無異常 都将執行 不受return 影響}

順序為:先執行try中的邏輯,如果正常執行,則跳轉到finally塊中執行,如果異常了,則會終止try塊中的邏輯,轉移到

catch塊中執行,最後還是會在finally完成最後的操作

《practical Java》讀書筆記概述:
《practical Java》讀書筆記概述:

實踐17:絕對不可輕視異常

當發生程式異常的時候,我們有哪些處理方式

1.捕獲并處理,防止它進一步傳播 2.捕獲并在此抛出它,傳播給它的調用者  3.捕獲它,并抛出一個新的異常給調用者 4.不捕獲這個異常,任由它傳播

這裡需要用到引用一個新的概念:抛出異常,通過throws來完成

正常情況下,第一個處理方式是最常見的,實踐16中也是采用了第一種處理方式

後續三種我們将在實踐18~20中一一介紹

《practical Java》讀書筆記概述:
《practical Java》讀書筆記概述:

實踐18:千萬不要遮掩異常

在處理try塊彙總的異常時,如果catch擷取finally中又抛出異常,那麼之前的異常會被覆寫

優先級:finally>catch>try

我們知道,finally是不受之前是否異常影響的,都将會執行,但是特殊情況下finally語句照樣

也會産生異常,那到底要如何處理呢?那就是将異常存放在Vector中

《practical Java》讀書筆記概述:
《practical Java》讀書筆記概述:

實踐19:明确throws字據的缺點

我們在開發過程中,經常會調用一些公用的函數(作者給了一個很通俗的名稱:工蜂型函數),而這些函數

有可能會産生異常(比如調用資料庫連接配接的方法),這時候處理異常有兩種方式

一種是函數自身處理,一個是調用端來處理.個人偏好是函數本身來處理,否則有10處地方調用這個函數

就要捕獲10次

實踐20:細緻而全面的了解throws子句

看的不是很懂,但是根據作者的demo,我了解的是作者想表達的意圖是當重寫函數的時候

函數抛出的異常範圍不能大于該函數抛出範圍,當然也可以不抛出異常(子類抛出異常的範圍不能大于父類)

《practical Java》讀書筆記概述:
《practical Java》讀書筆記概述:

實踐21:使用finally避免資源洩露

簡單的描述就是在異常進行中,java規範是通過finally來做一些善後的事情(包括釋放資源等)

實踐23:将try/catch區段置于循環之外

弦外音:不能循環調用try/catch區段,而應該在一個try/catch中調用循環

實踐27:抛出異常前線将對象恢複為有效狀态

弦外音:将狀态變量等處理放在可能處理異常之後,保證狀态不受異常影響

實踐31:如欲進行字元串結合,StringBuffer優于String

弦外音:對于需要頻繁處理字元拼接組合的地方,請使用StringBuffer,或則對于稍微複雜的操作,請使用StringBuffer

實踐33:慎防未使用的對象

弦外音:如果一個判斷兩選一,請不要都建立之,然後根據if else 來選擇其中一個對象

   換句話說,使用的時候才去建立對象

實踐34:将同步化降至最低

弦外音:盡量少用同步操作,諸如synchronized等,除非你需要同步資源

實踐35:盡可能使用stack變量

弦外音:盡量使用局部變量(stack)來代替全局變量(heap)

實踐36:使用static,final和Privatae函數以促成inlining

略,後續在認真看

略,對多線程感興趣的朋友可以看看,都比較基礎

實踐59.運用接口來支援多繼承

弦外音:java雖然不支援多繼承(class a extends b,c)但是卻可以通過接口

來完成多實作(class a implements a,b ,c......)

實踐60.避免接口函數發生沖突

弦外音:假如類A實作了B,C兩個接口,但是B和C都有方法test()

這樣A要實作B還是C的test()方法呢,作者給出了解決方式,個人覺得方法很贊

java中很多庫都使用了類似的方式來解決這類問題

即讓D繼承B接口(重命名接口,避免沖突),然後class A Implements D,C

實踐61、62:

關于繼承和接口 抽象類等知識點 

實踐63~66

關于類引用之間的操作 包括淺克隆 深克隆等

實踐68:在構造函數内調用non-final函數是要當心

這個記得初學java時候,比較難搞懂的一道題目,了解其機制

需要明白java對一個類的初始過程

我們結合代碼來看下

PDF和筆記源碼稍後上傳