比較 Java 靜態(tài)工廠方法與構(gòu)造函數(shù)

1 什么是靜態(tài)工廠方法

Java 靜態(tài)工廠方法是在方法前加上 public static,讓這個方法變?yōu)楣_、靜態(tài)的方法。該方法返回該類的一個實例,就好像一個工廠生產(chǎn)出一個產(chǎn)品。所以稱之為靜態(tài)工廠方法。在 Boolean.java 中有一個靜態(tài)工廠方法示例:

public static Boolean valueOf(boolean b) {
        return (b ? TRUE : FALSE);
    }

這里返回了一個 Boolean 實例。

2 比較靜態(tài)工廠方法與構(gòu)造函數(shù)

2.1 名稱

靜態(tài)工廠方法可以根據(jù)返回實例的性質(zhì),定義出具有自描述性質(zhì)的方法名稱。比如 BigInteger 類定義了一個靜態(tài)工廠方法 probablePrime,用于返回一個 BigInteger 類型的素數(shù):

public static BigInteger probablePrime(int bitLength, Random rnd) {
        if (bitLength < 2)
            throw new ArithmeticException("bitLength < 2");

        return (bitLength < SMALL_PRIME_THRESHOLD ?
                smallPrime(bitLength, DEFAULT_PRIME_CERTAINTY, rnd) :
                largePrime(bitLength, DEFAULT_PRIME_CERTAINTY, rnd));
    }

但如果是構(gòu)造函數(shù),那么只能是類名,比如上例中的 BigInteger。這樣就無法從名稱上判斷返回的 BigInteger 實例到底有什么性質(zhì)。

2.2 緩存

每次調(diào)用構(gòu)造函數(shù)都會創(chuàng)建新的對象。如果需要事先創(chuàng)建好對象,并緩存起來,以供后期復(fù)用。那么構(gòu)造函數(shù)方式就不能滿足該需求。而靜態(tài)工廠方法就可以實現(xiàn)。比如 Boolean.java 中的 valueOf 方法,實際上返回的是實現(xiàn)創(chuàng)建好的靜態(tài)屬性 TRUE 與 FALSE:

public static Boolean valueOf(boolean b) {
        return (b ? TRUE : FALSE);
    }

下面是事先靜態(tài)初始化好的TRUE 與 FALSE:

/**
     * The {@code Boolean} object corresponding to the primitive
     * value {@code true}.
     */
    public static final Boolean TRUE = new Boolean(true);

    /**
     * The {@code Boolean} object corresponding to the primitive
     * value {@code false}.
     */
    public static final Boolean FALSE = new Boolean(false);

2.3 子類

擁有構(gòu)造函數(shù)的類,可以被子類所繼承。但只有靜態(tài)工廠方法的類卻不行??梢允褂妙惤M合方式來解決這一問題。

2.4 總結(jié)

比較 靜態(tài)工廠方法 構(gòu)造函數(shù)
名稱 可根據(jù)情況自定義名稱 只能是類名
緩存 可調(diào)用重復(fù)對象 每次調(diào)用都創(chuàng)建新的對象
子類 不能被子類繼承 可以被子類繼承

3 靜態(tài)工廠方法命名方式

關(guān)鍵詞 說明 入?yún)€數(shù) 示例
from 類型轉(zhuǎn)換,A 類型轉(zhuǎn)換為 B 類型。 1 public static Date from(Instant instant)
of 聚合,做合并。 n public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3)
instance 返回實例,可能是新建的,也可能是復(fù)用已創(chuàng)建的實例。 n public static Object instance(int length)
create 返回新建的實例。 n public static Object create(int length)
type 工廠方法不在要返回的類實例中,type 是要返回的類名稱。 n public static <T> ArrayList<T> list(Enumeration<T> e)

最后一個示例,方法定義在 Collections 中,要返回的是 ArrayList 實例,所以被命名為 list。

public static <T> ArrayList<T> list(Enumeration<T> e) {
        ArrayList<T> l = new ArrayList<>();
        while (e.hasMoreElements())
            l.add(e.nextElement());
        return l;
    }

建議優(yōu)先考慮使用靜態(tài)工廠方法來實例化類。


JoshuaBloch. Effective Java中文版.3版[M]. 機械工業(yè)出版社, 2018.p.4-8.

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容