我想問爲什麼java在非靜態對象之前初始化靜態對象?在Java中初始化的順序
class Cupboard {
Bowl b3 = new Bowl(3);
static Bowl b4 = new Bowl(4);
Cupboard() {}
static Bowl b5 = new Bowl(5);
}
我想問爲什麼java在非靜態對象之前初始化靜態對象?在Java中初始化的順序
class Cupboard {
Bowl b3 = new Bowl(3);
static Bowl b4 = new Bowl(4);
Cupboard() {}
static Bowl b5 = new Bowl(5);
}
因爲曾經創建類的任何實例之前被創建和初始化(類加載過程中)一類的靜態成員 - 他們可以訪問:在這個例子B3
會後,B4和B5進行初始化而無需創建類的實例。非靜態成員是按每個實例創建的,因此等待直到爲該實例創建了一個要初始化的實例。
static
變量在加載類時被初始化。
實例變量(非靜態)在構造該類的一個對象之後進行初始化,該類是在加載該類之後進行的。
因爲該類在實例之前被初始化。當類加載時,Java運行任何靜態塊並初始化靜態變量。但是,在創建實例之前,不會創建或初始化非靜態的實例變量。
試想靜態變量是類的變量,而不是該類的對象。這比實例高一級。如果Java支持元類,那麼類將在元類聲明時實例化,並且即使沒有這些類的實例存在,也可以訪問它們的靜態成員。所以你真的需要在靜態之前有靜態成員。
靜態變量在加載類時被初始化。
實例變量在構造實例時被初始化。大多數情況下,這是在類完全初始化之後,但與其他人所寫的相反,初始化靜態變量時可能會發生這種情況。例如,它是很常見的靜態常量一類常用的情況下,像這樣: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;
}
[...]
}
這名被初始化爲「欄」。
+1正準備發佈相同的東西。 – mikej 2010-04-16 12:21:15
謝謝戴維,但是當「班加載」發生時呢?編譯完成後還是想從課堂上創建實例? – 2010-04-16 12:38:23
@ M.H:您的類在您第一次嘗試使用它時運行時加載,或者您明確告訴VM加載它。那時候靜態的東西被初始化了。如果可以在編譯時確定某些值,則編譯器可能已將其內聯。 – 2010-04-16 13:05:24