Java 構造方法私有化與單例模式

先看一個程序:

class Singleton { // 定義一個類
    public void print() {
        System.out.println("Hello World");
    }
}

public class Test {
    public static void main(String args[]) {
        Singleton inst = null; // 聲明對象
        inst = new Singleton(); // 實例化對象
        inst.print(); // 調用方法
    }
}

上面的Singleton類裏是存在構造方法的(如果一個類中沒有明確的定義一個構造方法的話,會自動生成一個無參默認的構造方法),現在把構造方法修改一下:

class Singleton { // 定義一個類
    private Singleton() {
    } // 構造方法私有化

    public void print() {
        System.out.println("Hello World");
    }
}

我們知道,構造方法被私有化,就無法在類外部實例化Singleton對象。

那麼,此時,如何在Test類裏面得到Singleton類的實例化對象並且調用print()方法?

首先,這個類的構造方法被私有化,只能被本類所調用,所以可以在本類中產生本類的實例化對象:

class Singleton { // 定義一個類

    Singleton instance = new Singleton();//在本類中產生本類的實例化對象

    private Singleton() {
    } // 構造方法私有化

    public void print() {
        System.out.println("Hello World ");
    }
}

我們知道,此時instance 屬性只是一個普通屬性,必須在類實例化對象後再可以使用,要想不需要實例化對象直接使用,可以使用static聲明:

class Singleton { // 定義一個類
    static Singleton instance = new Singleton();

    private Singleton() {
    } // 構造方法私有化

    public void print() {
        System.out.println("Hello World");
    }
}

public class Test {
    public static void main(String args[]) {
        Singleton inst = null; // 聲明對象
        inst = Singleton.instance; // 實例化對象
        inst.print(); // 調用方法
    }
}

但是,我們知道,類中的全部屬性都應該封裝,以上的instance屬性也應該封裝:

private static Singleton instance = new Singleton();

而封裝之後要想取得屬性。要編寫getter方法,不過這裏的getter方法應該也由類名稱直接調用,定義爲static型,getInstance()方法:

class Singleton { // 定義一個類
    private static Singleton instance = new Singleton();

    private Singleton() {
    } // 構造方法私有化

    public void print() {
        System.out.println("Hello World ");
    }

    public static Singleton getInstance() {
        return instance;
    }
}

public class Test {
    public static void main(String args[]) {
        Singleton inst = null; // 聲明對象
        inst = Singleton.getInstance(); // 實例化對象
        inst.print(); // 調用方法
    }
}

爲什麼這麼做呢?此時程序之中的instance屬性,屬於static,那麼,不管有多少個Singleton類的對象,都共同擁有同一個instance屬性

我們再來看,若getInstance()方法修改如下:

    public static Singleton getInstance() {
        instance = new Singleton();
        return instance;
    }

此時,發現,每調用一次getInstance()方法,就會實例化一個Singleton對象,這樣的話,實例化對象就不是唯一的了,所以,這種情況不能讓它出現,怎麼辦?可以在定義instance屬性的時候增加一個final關鍵字:

 private static final Singleton INSTANCE = new Singleton() ;

於是,最後的代碼就變成了這樣:

class Singleton { // 定義一個類
    private static final Singleton INSTANCE = new Singleton();

    private Singleton() {
    } // 構造方法私有化

    public void print() {
        System.out.println("Hello World .");
    }

    public static Singleton getInstance() {
        return INSTANCE;
    }
}

public class Test {
    public static void main(String args[]) {
        Singleton inst = null; // 聲明對象
        inst = Singleton.getInstance(); // 實例化對象
        inst.print(); // 調用方法
    }
}

這樣的設計在設計模式上講就稱爲單例設計模式(Singleton)

單例設計模式的類型:

(1)餓漢式單例模式:當類裝載的時候就會創建類的實例,不管你用不用,先創建出來,然後每次調用的時候,就不需要再判斷。上面的程序就屬於餓漢式單例模式,

(2)懶漢式單例類:每次獲取實例都會進行判斷,看是否需要創建實例,如果一直沒有人使用的話,那就不會創建實例。代碼如下:

class Singleton { // 定義一個類
    private static Singleton instance;

    private Singleton() {
    } // 構造方法私有化

    public void print() {
        System.out.println("Hello World .");
    }

    public static Singleton getInstance() {
        if (instance == null) { // 沒有實例化
            instance = new Singleton(); // 實例化
        }
        return instance;
    }
}

小結:單例模式的特點?

(1)構造方法被私有化(private);
(2)只能夠通過getInstance()方法取得Singleton類的實例化對象,這樣不管外部如何操作,最終也只有一個實例化對象;
(3)在單例設計模式之中,一定會存在一個static方法,用於取得本類的實例化對象。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章