2016-03-28 63 views
2

我認爲一個共同的Singleton設計模式:單例設計模式,靜態訪問非靜態?

public class Singleton{ 

    private static Singleton instance; 

    private Singleton(){} 

    public static Singleton getInstance(){ 

    if(instance==null) 
     instance=new Singleton(); 

    return instance; 

    } 
} 

據我所知,costructors都是非靜態的方法,因爲他們可以使用上下文引用「本」(這是在靜態環境中禁止的)。另一方面,靜態成員只能訪問靜態成員。

那麼靜態成員getInstance()是如何訪問非靜態成員構造函數呢?

+1

可以從任何地方調用構造函數。(在這裏,因爲它是單身人士 - 所以在課堂內的任何地方) – Hackerdarshi

+1

在這裏,創建一個新的實例。它不像我們在你的靜態方法中調用'Singleton()'(就像我們將調用另一個方法)。當然這是不可能的。 –

+2

* costructors是非靜態方法*。構造函數是構造函數。方法有一個返回類型。 –

回答

4

當您看到像new Singleton()這樣的對象創建時,您必須區分new運算符與構造函數代碼,或者更精確地說是初始化代碼。

new運營商是「」靜態方法調用。它不需要一個對象的實例,因爲它創建了一個實例。

構造函數的代碼更多的是「」,如「的實例方法,只是它沒有返回類型。但它可以訪問this參考。

至少當你深入到生成的字節碼中時你會看到不同之處。 new運算符將導致該字節碼指令。

NEW yourpackage/Singleton 

該指令僅在內存中創建對象。請參閱jvms-6.5.new

創建對象後,通過執行初始化代碼進行初始化。在字節碼中,它看起來像:

INVOKESPECIAL yourpackage/Singleton.<init>()V 

初始化程序代碼不僅僅是構造函數代碼。它調用超類的初始化器並初始化實例字段。

另見java virtual machine specification 2.9

在Java虛擬機的水平,用Java編程語言(JLS§8.8)每一個構造表現爲具有特殊名稱的實例初始化方法。該名稱由編譯器提供。由於名稱不是有效的標識符,因此不能直接在用Java編程語言編寫的程序中使用。實例初始化方法只能通過invokespecial指令(§invokespecial)在Java虛擬機內調用,並且只能在未初始化的類實例中調用它們。實例初始化方法需要從中派生構造函數的訪問權限(JLS§6.6)

1

構造函數不是方法。靜態方法與類相關聯,非靜態方法與該類的實例相關聯。您不能從靜態方法調用非靜態方法,因爲沒有與靜態方法關聯的實例。您可以從靜態方法調用構造函數,因爲構造函數與類關聯,而不是實例。

構造函數只有在實例化對象後,即在構造函數被調用後才能使用「this」引用。