2012-05-09 103 views
2

我想從下面的代碼中瞭解y靜態變量b的值未初始化,儘管該值已在構造函數中初始化。構造函數java中的靜態變量初始化java

public class A { 
     private static B b = null; 
     public A() { 
      if (b == null) 
      b = new B(); 
     } 

     public static void main(String[] args) { 
      b.func(); 
     } 
    } 

感謝 Punith

+2

因爲你已經在創建A'的'一個實例製成的'B'相關的初始化。 – user1329572

+0

[靜態變量初始化java]的可能的重複(http://stackoverflow.com/questions/1642347/static-variable-initialization-java) – nandeesh

回答

6

你永遠不調用A()構造函數。 主函數是靜態的,這意味着它不屬於A的一個實例。因此,當你輸入main時,沒有創建A的實例,所以構造函數從未被調用過,而b仍然是空的。

如果您運行此代碼,您應該得到一個NullPointerException。

如果添加 new A();在b.func()之前的 ;那麼你會沒事的(代碼將仍然是奇數)

+0

是的,謝謝 –

7

錯誤 - 不喜歡這樣寫道:

public class A { 
     private static B b = null; 

     static { 
      b = new B(); 
     } 

     public A() { 
     } 

     public static void main(String[] args) { 
      b.func(); 
     } 
    } 
+0

如果你能詳細說明爲什麼它會更有幫助,張貼在OP上做錯的方式。 – posdef

+2

但這在語義上是不同的,對吧?在OP發佈的代碼中,除非對象實際已經被粘貼,否則該字段不會被初始化。 – aioobe

+0

夥計們,我想知道在調用main方法之前,構造函數會被調用。所以對象將被初始化。或者是上面的語句錯誤? –

2

你的問題要求幫助你「理解爲什麼」的行爲是這樣的。原因是當您調用靜態方法main()時,不會調用類A的構造函數。

如果要實例化A類型的對象,則會調用構造函數並引用B初始化。

作爲一個良好的做法,我會建議在執行它之前始終實例化一個類,然後從static void main()開始執行它。如果你開始使用框架(比如Spring),你最好創建你的類的實例,而不是寫類似於編寫過程代碼的靜態方法。

而不訴諸靜態initialisers這裏遵循的原則大綱,一個解決辦法是...

public class A { 
    private static B b = null; 

    public A() { 
     if (b == null) 
      b = new B(); 
    } 

    public static void main(String[] args) { 
     A a = new A(); 
     a.callFunc(); 
    } 

    public void callFunc() { 
     b.func(); 
    } 
} 

正如你可以看到你需要一種方式來引用b.func() method所以我加了a.callFunc()這個原因

3

我覺得你的問題有兩個部分:

1)爲什麼靜態變量b的值沒有初始化,雖然 該值是在構造函數中初始化的嗎?

答:首先,在main()之前不調用構造函數。構造函數在main()中調用。每當在main()使用new爲:

public static void main(String args[]){ 
MyClass myclass= new MyClass() 
} 

則僅構造函數被調用。

在您的代碼中,靜態變量b未初始化,因爲您正在構造函數A()中初始化它,但此構造函數從未被調用過。你可以調用A()構造函數代碼爲:

public static void main(String[] args) { 
      A a=new A(); // constructor gets called here. 
      b.func(); 
     } 

2)什麼是初始化靜態變量的正確方法?

初始化靜態變量的正確方法是使用靜態初始化塊,而不是在構造函數中初始化它們,如duffymo給出的答案中所示。

static { 
    b = new B(); 
} 

您還可以使用:

public class A { 
     private static B b = new B(); 

     public A() { 
     } 

     public static void main(String[] args) { 
      b.func(); 
     } 
    }