簡體   English   中英

使用靜態工廠的不可變類

[英]Immutable class using static factories

我正在學習Joshua Bloch的Effective Java,在那里他解釋了實現不可變類的不同方法。 為了防止子類化,一種方法是使用final 更復雜的方法是將構造函數設為私有,從而防止外部訪問,並使用靜態工廠進行對象創建。

但是,我不明白這句話:

public class Complex {
    private final double re;
    private final double im;

    private Complex(double re, double im) {
        this.re = re;
        this.im = im;
    }

    public static Complex valueOf(double re, double im) {
        return new Complex(re, im);
    }
}

它最靈活,因為它允許使用多個包私有實現類。

我理解外部客戶端在沒有公共/受保護構造函數的情況下將其子類化是不可能的,但是不理解術語“多包私有實現類”所傳達的內容。

注意:這是Effective Java中的第15項(最小化可變性)。

據我記得約書亞然后談論EnumSet (但我不記得他提到的背景)。

EnumSet是抽象的,也有靜態方法noneOf等有兩類擴展EnumSetJumboEnumSetRegularEnumSet

您不能直接使用它們,因為它們是包私有的(沒有public關鍵字):

class RegularEnumSet<E extends Enum<E>> extends EnumSet<E>
class JumboEnumSet<E extends Enum<E>> extends EnumSet<E>

java.util包只能直接使用它們(如果我們不談論反射或其他技術)。

您只需使用EnumSet靜態方法,它就會返回一些您不應該注意的EnumSet子類。

看一下noneOf方法實現:

public static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType) {
    Enum<?>[] universe = getUniverse(elementType);
    if (universe == null)
        throw new ClassCastException(elementType + " not an enum");

    if (universe.length <= 64)
        return new RegularEnumSet<>(elementType, universe);
    else
        return new JumboEnumSet<>(elementType, universe);
}

這是多個包私有實現

類不能被子類化的唯一方法是將類標記為final 由於這個類不是final所以它可以是子類 ,如下所示:

public class Complex {

    private final double re;
    private final double im;

    private Complex(double re, double im) {
        this.re = re;
        this.im = im;
    }

    //methods...

    static class SubComplex1 extends Complex {

        private SubComplex1(double re, double im, double x) {
            super(re, im);
            //more elements...
        }
        //you can define/override methods here
    }

    public static Complex valueOf(double re, double im, double x) {
        return new SubComplex1(re, im, x);
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM