2010-04-16 111 views
5

我想問爲什麼java在非靜態對象之前初始化靜態對象?在Java中初始化的順序

class Cupboard { 
    Bowl b3 = new Bowl(3); 
    static Bowl b4 = new Bowl(4); 
    Cupboard() {} 
    static Bowl b5 = new Bowl(5); 
} 

回答

17

因爲曾經創建類的任何實例之前被創建和初始化(類加載過程中)一類的靜態成員 - 他們可以訪問:在這個例子B3
會後,B4和B5進行初始化而無需創建類的實例。非靜態成員是按每個實例創建的,因此等待直到爲該實例創建了一個要初始化的實例。

+0

+1正準備發佈相同的東西。 – mikej 2010-04-16 12:21:15

+0

謝謝戴維,但是當「班加載」發生時呢?編譯完成後還是想從課堂上創建實例? – 2010-04-16 12:38:23

+0

@ M.H:您的類在您第一次嘗試使用它時運行時加載,或者您明確告訴VM加載它。那時候靜態的東西被初始化了。如果可以在編譯時確定某些值,則編譯器可能已將其內聯。 – 2010-04-16 13:05:24

2
  • static變量在加載類時被初始化。

  • 實例變量(非靜態)在構造該類的一個對象之後進行初始化,該類是在加載該類之後進行的。

3

因爲該類在實例之前被初始化。當類加載時,Java運行任何靜態塊並初始化靜態變量。但是,在創建實例之前,不會創建或初始化非靜態的實例變量。

1

試想靜態變量是類的變量,而不是該類的對象。這比實例高一級。如果Java支持元類,那麼類將在元類聲明時實例化,並且即使沒有這些類的實例存在,也可以訪問它們的靜態成員。所以你真的需要在靜態之前有靜態成員。

2

靜態變量在加載類時被初始化。

實例變量在構造實例時被初始化。大多數情況下,這是在類完全初始化之後,但與其他人所寫的相反,初始化靜態變量時可能會發生這種情況。例如,它是很常見的靜態常量一類常用的情況下,像這樣:FOO_BAZ初始化之前一審

class Foo 
{ 
    private static final Foo FOO_BAR = new Foo("bar"); 
    private static final Foo FOO_BAZ = new Foo("baz"); 

    private final String name; 

    public Foo(String n) 
    { 
     name = n; 
    } 

    [...] 
} 

這名被初始化爲「欄」。