原因
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...