Effective Java 精簡實用版

2021-06-11 09:17:02 字數 3619 閱讀 3167

原因

1.     

靜態工廠具有名字

i.          對於兩個建構函式,如果引數型別和個數相同,則只能使用不同的順序進行區分,而使用工廠函式可以為這兩個建構函式指明不同的名稱

ii.          如果有多個建構函式,可考慮用靜態工廠方法替換

2.     

不要求建立新物件

i.          當系統需要該類的n或1個例項,如果使用建構函式,則每次呼叫都會建立乙個例項,可通過單例或多例模式重用已有例項

3.     

返回原型別的子型別物件

i.          對於乙個繼承體系,在基類中宣告靜態工廠方法,根據type返回不同的子類例項,且該子類為package 或 private,可以向客戶端隱藏子類。

命名規範

getinstance  

,如inte***ce newinstance(class a);

代替clone

valueof :

返回的例項與原有例項具有相同的值,如 float和float  , ***config 和 ***

通用約定

對稱性:如果x 和y屬於不同的類,就要注意了

不需要對null做特殊的檢查,null instanceof mytype  返回false

object

中規範要求,如果equals返回true,則 兩個物件的hashcode 產生相同的整數值,如果equals使用邏輯判斷,而hashcode未改寫(使用引用位址),該物件作為hashmap或hashset 的key,equals相同的兩個物件作為不同的key

編寫方法:

1.  

對每乙個關鍵域(equals用到,而且非冗餘)計算雜湊值 c

boolean :   f?0:1;   

byte  char  short  int  

:  (int ) f

long :

(int) (f ^ (f >>>32))

float :  float.floattointbits(f)

double: double.doubletolongbits(f).floattointbits

物件引用,呼叫該物件的hashcode

2.  

公式  17*37+c

3. 判斷 hashcode和equals 方法是否一致

強烈建議滿足 (x.compareto(y)==0)==(x.equals(y)),否則如treeset中 equals不同而compareto相同的物件只有乙個 實現

直接進行型別轉換,不進行型別和空判斷

頂層類只有 default和public,盡量為default

成員(函式,屬性,內嵌類)可以有 private default  protected public四種,先都宣告為private,在需要的時候修改

非零長度的陣列總是可變的,所以具有公有的靜態final陣列域總是錯誤的,應該替換為乙個方法,返回乙個拷貝

1. 

不提供修改方法

2. 

該類不可繼承 final

3. 

所有域都是 private final

4. 

如果類指向可變物件的引用,保證客戶無法獲得該引用

5. 

如果類不能做成不變的,盡量限制其可變性,比如建構函式完成可變性建立

好處是:不要求執行緒同步

1. 防止構造層次結構的型別框架。 對於乙個類體系,有基本的功能和擴充套件,對於這些基本功能應該通過繼承實現,而可選的功能應該通過介面和實現類來引入

常量不應該使用介面實現,如果該常量類列舉,應該使用 【型別安全列舉類】 來實現,否則使用不可被例項化的工具類 來定義這些常量

策略模式可以和簡單工廠模式相結合,將具體的策略類實現為工廠的private static member class,對外部隱藏

巢狀類只定義在類內部,主要為父類服務,分為 static member class, nonstatic memeber class, annonymous class, local class.

成員類類似於普通的成員,可以訪問父類的成員,包括宣告為private的

選擇:如果成員類的每個函式不需要訪問外部類的非靜態資訊,則使用 static member class,否則為 nonstatic member class,如果該類只使用一次,且定義了介面或基類使用 annonymous class,local class只在方法內部定義的類,很少使用

static member class

為public,通常作為父類的乙個子部分,如常量資訊的存放;為private 通常作為父類的乙個元件,比如map和map.entity,而且該類不允許被外部訪問,該類不能訪問父類的非靜態成員。

non static member class

多作為介面卡,可以訪問父類的非靜態成員。

當選擇時,考慮是否需要訪問父類的非靜態成員,不需要就是用static member class

定義乙個類來代替列舉型別,該類私有建構函式,

為每乙個列舉常量定義 final static的物件,如public static final suit clubs=new suit("club");

呼叫時 suit.clubs。

被外部呼叫的方法,使用異常標示引數非法,如illegalargumentexception  nullpointerexception  indexoutofbound***ception.

非公有的 使用assert處理

有些引數,方法本身不使用,儲存起來以後使用,檢測尤為重要,如建構函式

當引數檢查非常昂貴,或者不切實際時,就不要引數檢查了

過載方法的呼叫是在編譯期決定的,如 fun(set s)  , fun(collection c)。 實參為 collection tests=new collection ;  如果你以為會呼叫fun(set s) 那就錯了,因為是在編譯期決定,而引數型別是collection,所以會呼叫 fun(collection c).

這種使用方式容易混淆,所以應該避免引數為同一體系的過載用法,或者更嚴格點,避免兩個相同引數數目的過載方法

函式 cheese getcheeses() 返回 new cheese[0] 而不是null,好處有二,1. 符合邏輯需要 ; 2.  不需要對null額外處理

如果函式中用到多次 new cheese[0],可以將其宣告為常量  final static cheese null_cheese_array=new cheese[0] 然後在函式中使用。

當迴圈判斷中涉及到乙個方法呼叫,且可以保證每次迭代中這個方法呼叫返回相同的結果,則使用  for(int i=0, n=list.size; i將呼叫放在第乙個;中

常用的已經在 命名規範 中描述,下面說些特殊的

1. 轉換物件型別的方法  totype  ,如 toarray

2. 返回物件的一種表現形式  astype,如 asxml

3. 返回物件同值的primitive型別  typevalue  如 intvalue

4. 靜態工廠: valueof (返回的例項與原有例項具有相同的值) 和 getinstance()

5. boolean

型別的變數和函式很類似,不過是省略了is,如 initialized和 isinitialized

《effective Java》讀後筆記

為什麼區域性變數要宣告為 final 在jdk 1.8 之前,不用final修飾會編譯報錯。在jdk 1.8 中,不用final修飾不會報錯,但是一旦改變了變數的值就會報錯 區域性類如果乙個內部類需要在多個方法之外仍然是可見的,或者是它太長了,不適合於放在方法內部,就應該使用成員類。如果成員類的每個...

Effective Java閱讀筆記

通用程式設計 將區域性變數的作用域最小化,可以增強 的可讀性和可維護性,並降低出錯的可能性。要使區域性變數的作用域最小化,最有力的方法就是在第一次使用它的地方宣告。如果變數在使用之前宣告,只會造成混亂,過早地宣告區域性變數不僅會使它的作用域擴充套件,而且結束地也過於晚了。不要重新造輪子,一般而言,類...

Effective Java 學習筆記 6

及時消除不使用的物件的引用,理論上,帶有記憶體管理的語言是不存在記憶體洩漏的,但是如果對物件的操作不當,也是可能會造成記憶體洩漏.如有乙個stack,其pop函式如下.public object pop if element.length 0 return null return element s...