Effective Java(1):靜態工廠方法代替構造器

建立類的實例最多見的是new 除此外還可使用靜態工廠方法,來封裝實例的細節,而且能控制實例的數量,減輕jvm的堆棧中的壓力。靜態工廠方法最主要的特色是:每次被調用的時候,不必定要建立一個新的對象。java

靜態工廠方法:靜態工廠方法與別的靜態方法沒有什麼區別,只不過該方法產生的類對象,不作其餘事情。緩存


靜態工廠方法與構造器不一樣的優點在於:jvm

  1. 靜態工廠方法有名稱函數

    靜態工廠方法能夠突破構造函數不能自由命名的限制,對於不一樣的工廠方法能夠採用不一樣的會意的名字,是程序具備更好的可讀性。spa

  2. 沒必要在每次調用的時候都建立一個新對象code

    每次執行new語句時,都會建立一個新的對象。而靜態工廠方法每次被調用的時候,是否會建立一個新的對象徹底取決於方法的實現。
    orm

  3. 靜態工廠方法能夠返回原返回類型的任何子類型的對象對象

    new語句只能建立當前類的實例,而靜態工廠方法能夠返回當前類的子類的實例,這一特性能夠在建立鬆耦合的系統接口時發揮做用。接口

    靜態工廠方法是用來產生對象用的,至於產生什麼類型的對象沒有限制,這就意味這隻要返回原返回類型或原返回類型的子類型均可以。這樣就能夠更好達到封裝的目的,下降API的數目和用戶的使用難度。
    get

  4. 在建立參數化類型實例的時候,使代碼變得更加簡潔

    例如,在調用參數化類的構造器時,即便類型參數很明顯,也必須指明:

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

        隨着參數類型的愈來愈長、複雜,這一冗長的構造器參數說明也變得痛苦起來。可是有了靜態構造方法,編譯器就能夠替你找到類型參數,這被稱做類型推導(type inference)。例如:假設HashMap提供瞭如下靜態工廠:

public static <K,V> HashMap<K,V> newInstance() {
    return new HashMap<K,V>();
}

有了這個靜態工廠方法,就能夠用如下代碼代替上述複雜繁瑣的聲明:

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



利用特色3,靜態工廠方法可用來建立如下類的實例。

  1. 單例類:只有唯一的實例的類。

  2. 枚舉類:實例的數量有限的類。

  3. 具備實例緩存的類:能把已經建立的實例暫且存放在緩存中的類。

  4. 具備實例緩存的不可變類:不可變類的實例一旦建立,其屬性值就不會被改變。



靜態工廠方法的缺點

  1. 類若是不含有公有的或受保護的構造器,就不能被子類化

    準確理解:若是父類沒有提供Public的或者Protected的構造方法,那麼使用靜態工廠方法,將沒法根據父類去獲取到子類的實例。

  2. 靜態工廠方法與其餘的靜態方法實際上沒有任何區別

    比較流行的規範是把靜態工廠方法命名爲valueOf或者getInstance。

相關文章
相關標籤/搜索