java 單例模式

java單例模式

今天和同事在項目中用了一下單例模式,閒下來瞭解了一下單例模式的實現方式。參考了 http://cantellow.iteye.com/blog/838473 這篇博客。瞭解到主要有懶漢模式和餓漢模式兩種。前者實現了咱們所知道的lazy load。
在這裏我選了兩種實現方式本身實現了一下。

餓漢

public class Singleton {
    public static String NAME = "Singleton";
    private static Singleton singleton = new Singleton();

    private Singleton() {
        System.out.println("initial Singleton");
    }

    public static Singleton getSingleton() {
        return singleton;
    }
}

懶漢

public class InnerSingleton {

    public static String NAME = "InnerSingleton";

    private static class Singleton {
        private static final InnerSingleton INNER_SINGLETON = new InnerSingleton();
    }

    private InnerSingleton() {
        System.out.println("initial InnerSingleton");
    }

    public static InnerSingleton getSingleton() {
        return Singleton.INNER_SINGLETON;
    }
}

思考

看了類加載和類初始化的一些相關知識,參考 https://www.cnblogs.com/zhguang/p/3154584.html
無論使用什麼樣的類加載器,類都是在第一次被用到時,動態加載到JVM的。這句話有兩層含義:
Java程序在運行時並不必定被完整加載,只有當發現該類尚未加載時,纔去本地或遠程查找類的.class文件並驗證和加載;

當程序建立了第一個對類的靜態成員的引用(如類的靜態變量、靜態方法、構造方法——構造方法也是靜態的)時,纔會加載該類。Java的這個特性叫作:動態加載。
須要區分加載和初始化的區別,加載了一個類的.class文件,不覺得着該Class對象被初始化,事實上,一個類的初始化包括3個步驟:html

加載(Loading),由類加載器執行,查找字節碼,並建立一個Class對象(只是建立);
連接(Linking),驗證字節碼,爲靜態域分配存儲空間(只是分配,並不初始化該存儲空間),解析該類建立所須要的對其它類的應用;
初始化(Initialization),首先執行靜態初始化塊static{},初始化靜態變量,執行靜態方法(如構造方法)。

類初始化的時機分如下幾種狀況java

使用new關鍵字實例化對象的時候
讀取或設置一個類的靜態字段(被final修飾,已在編譯期把結果放入常量池的靜態字段除外, 舉個例子?)
調用一個類的靜態方法
使用java.lang.reflect包的方法對類進行反射調用的時候
當初始化一個類的時候,若是發現其父類尚未進行初始化,須要先初始化其父類
虛擬機啓動時要執行的主類(包含main()方法的類).net

當我把類加載和初始化分開來看時,我發現不管是餓漢模式仍是懶漢模式都是在調用getInstance方法時,纔會將構造器裏的話打印出來,這樣看是否都是懶漢模式呢?如今看起來實例都是在類初始化的時候建立的。留有疑問。

更新 解答疑問

public static void main(String[] args) {
        String a = Singleton.NAME;
        String b = InnerSingleton.NAME;   
    }

可使用這種方法觸發類的裝載,在這裏類的裝載=加載+初始化。使用上述方法的結果以下圖所示:
code

而若是隻裝載類,利用classloader,兩種方法是都不會打印出來的。但是若是利用classforname方法,是和上述截圖的結果一致的。這是由於,classforname除了會將類加載還會對static變量進行初始化,參考 https://blog.csdn.net/qq_27093465/article/details/52262340htm

相關文章
相關標籤/搜索