2016-09-14 71 views
1

我下面這個教程創建辛格爾頓和業主有意見時,下面http://www.journaldev.com/1377/java-singleton-design-pattern-best-practices-examples實例化發生在getInstance()或getInstance()之前嗎?

public class EagerInitializedSingleton { 

    private static final EagerInitializedSingleton instance = new EagerInitializedSingleton(); 

    //private constructor to avoid client applications to use constructor 
    private EagerInitializedSingleton(){} 

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

方法如果你的單例類沒有使用了大量的資源,這是 方式使用。但是在大多數場景中,爲文件系統,數據庫連接等創建的單例類爲 和我們應該避免實例化,除非客戶端調用 getInstance方法

的問題是:

他們說我們應該避免的實例化,直到除非客戶端調用getInstance方法 但正如我在這段代碼知道實例(對象實例)總是發生時類EagerInitializedSingleton負載和EagerInitializedSingleton僅僅只有當我們調用加載EagerInitializedSingleton.getInstance()
=>實例化將發生在時間getInstance()和前所未有getInstance()

參考:

靜態變量被初始化僅僅一次,在執行開始(當類加載器加載類首次)。 (從https://stackoverflow.com/a/8704607/5381331

所以,當被加載的類?
正好有兩種情況:
- 當執行新的字節碼時(例如,FooClass F =新FooClass();)
- 並且當字節碼使靜態參考一類(例如,系統。出) (從http://www.javaworld.com/article/2077260/learn-java/learn-java-the-basics-of-java-class-loaders.html

我錯了還是正確的。請給我一些消化。

回答

2

在這種情況下與特定的代碼,你可能正確

但是,如果你有的EagerInitializedSingletonstatic方法,或staticEagerInitializedSingletonfinal成員在您的代碼庫的getInstance調用之前某處引用的EagerInitializedSingletoninstance變量將初始化。

用相同的Class.forNameEagerInitializedSingleton類反射調用。

注(原諒這裏明顯),有聲明單,包括懶惰初始化或枚舉的替代方式。

+0

非常感謝您的明確解釋。它幫助我理解java很多 –

+0

@PhanVanLinh不客氣! – Mena

1

我認爲這個問題是當一個類被而不需要獲得實例加載,但其他一些原因。你假設這個類將在用戶第一次想要得到這個單例的實例時使用,但是這可能是由於其他原因發生的,他可能只是調用一個類加載器來獲得某些東西,或者使用一些第三方軟件來驗證類,任何想到涉及加載一個類但沒有得到一個單例的實例。

+0

您已完全混淆了類加載和類初始化。 –

1

他們說,我們應該避免,除非實例客戶端調用 直到getInstance方法

解決的辦法是延遲加載。 從wikipedia, Initialization-on-demand holder idiom

當類的東西是由JVM加載的類經過 初始化。由於類沒有任何靜態變量來初始化,所以初始化完成。直到JVM 確定必須執行LazyHolder,靜態類 定義中的LazyHolder纔會被初始化。靜態類 LazyHolder僅在靜態方法getInstance爲 在類Something上調用時執行,並且第一次發生這種情況時,JVM將加載並初始化LazyHolder類。

public class Something { 
    private Something() {} 

    private static class LazyHolder { 
    private static final Something INSTANCE = new Something(); 
    } 

    public static Something getInstance() { 
    return LazyHolder.INSTANCE; 
    } 
} 
相關問題