天天看點

淺析Effective Java 書中提到重要的規則-1

1. 考慮用靜态工廠方法代替構造器

分析:

   優勢一:靜态工廠方法有表達特殊意義的名字,可以進行需要的表述,更容易使用更容易于别人對你代碼的閱讀了解;

   優勢二:不需要在每次使用這個方法的使用建立新的對象。如果程式經常建立這個對象,而且建立一個對象花費的性能成本很高,那麼采用這種的方式可以極大提高性能;

   優勢三:靜态工廠方法可以傳回原類型任何子類型的對象;一些基于接口一的架構就使用了這個特點;

   優勢四: 建立參數化類型執行個體的時候,使得代碼更加的簡潔;

對比如下:

調用參數化構造器時:需要兩次提供參數類型

執行個體化代碼:

   Map <String ,List<String>> m = new HashMap<String,List<String>>();

采用靜态工廠方法後: 由編譯器比對類型參數,又叫:類型推導

可以編寫靜态工廠方法:

   public static Map<K,V> HashMap<K,V> newInstance()

   {

       return new HashMap<K,V>();

   }

執行個體化代碼如下:

Map <String,List<String>> m = HashMap.newInstance();

2.遇到多個構造器參數時要考慮用建構器

   當一個類執行個體化時需要指定初始化多個參數時,考慮采用建構器完成初始化工作;推薦builder模式;

有很多參數時,通常的處理是編寫很多個構造器,虛拟機根據比對選擇合适的構造器完成初始化。或者是采用java bean的模式,給每個成員變量定義 set方法完成初始化指派;這裡推薦一種更好的方式,Builder模式進行初始化工作;示例代碼見附件:Builder模式示例代碼;

好處:一旦賦予的參數值不比對時就會提示錯誤,不允許執行個體化。使用Builder建構器的代碼易于閱讀編寫,比Java bean的模型更加安全;

3.用私有構造器或者枚舉類型強化Singleton屬性

分析:    

   Singleton指的是僅僅被執行個體化一次的類。常常用來代表那些本質上唯一的元件。

4.通過私有構造器強化不可以執行個體化的能力

分析:

   很多的類我們不需要進行執行個體化,我們隻是使用它提供的靜态方法。我們可以使用private關鍵字修飾的構造器,使得類不能被執行個體化,不能被子類化;

因為在執行個體化或執行個體化一個類的子類的時候必須調用該類的構造器完成執行個體化。當它被private修飾了,就不能從外部調用,就不能完成執行個體化工作。

5. 避免建立不必要的對象

   這個主要展現在使用那些不可變對象身上比如String類型對象,在需要多次建立String對象時,例如:String str = new String("我是一個字元竄");這裡會建立2個對象,中加入在一個循環中調用這行代碼,可想而知會有多少個不必要的對象産生。

對于這種情況可以有以下幾種處理方式:

   第一: 單是對于String對象,我們可以利用虛拟機中的字元串常量池來重用對象;String str = "我是一個字元串" ;這裡會産生1個對象,之後有新的代碼: String str2 = "我是一個字元串" ; 那麼也不會再次産生新的對象了,str、str2 指向同樣的一個對象;

   第二: 盡量使用靜态工廠方法,避免新的對象産生;

   第三: 對于知道的不會改變的可變的對象,我們也盡量重用它。使用靜态代碼塊保證記憶體中隻有一個對象;

例如:

class   Student{

   private final Date birthday ;

   private static final Date boom_start;

   private static final Date boom_end;

   static {

       Calendar = gmtCal = Calender.getInstance(TimeZone.getTimeZone("GMT"));

       gmtCal.set(1946,Calendar.JANUARY,1,0,0,0);

       boom_start = gmtCal.getTime();

       boom_end = gmtCal.getTime();            

}

 說明:Student 類是一個可變的對象,但是計算每一個學生的生日的方式是不變的,每一個學生的生日是不變的,final保證之後不會發生改變;靜态代碼塊裡,Calender對象隻會被生産一次。

6. 消除過期的對象引用

   java虛拟機有垃圾回收器會定期清除過期的對象,但是當一個對象被無意識的保留下來了,垃圾回收器就不會回收了他,就可能造成記憶體洩露。比如Stack類自己管理着記憶體,垃圾回收器并比想人一樣知道哪些是可以回收的,是以當出棧時應該手動清空這些數組元素;

7. 避免使用終結方法

   終結方法(finalizer )是不可預測的,是一個危險的方法,使用這個方法可能會導緻系統行為不穩定,性能下降,以及可移植性降低等;當然也有它的用處,不推薦重寫;

   值得引起重視的: 終結方法裡建立銷毀對象會比不使用終結方法建立銷毀對象速度慢幾百倍;

                   不應該利用終結方法來更新重要對象的持久狀态,因為這個方法的執行優先級較低,不能保證及時被執行;

                   也有顯示終結方法運用的地方,InputStream,OutputStream 等 IO流進行中會顯示的調用close()方法關閉流;

   使用情況: 作為安全網 或者用于終止本地非關鍵的資源檔案;子類重寫了父類的終結方法,應該確定調用父類的終結方法(super.finalizal方法)

繼續閱讀