據說Java中的靜態塊只在加載該類時運行一次。但它實際上意味着什麼?在哪一點上是由JVM(Java虛擬機)加載的類?「何時加載類」實際上意味着什麼?
是否在該類中的主要方法被調用時?並且是否在main方法開始執行時也加載了同一類的所有超類?
考慮到A擴展B和B擴展C.所有都有靜態塊。如果A有主要方法,那麼靜態塊的執行順序是什麼?
據說Java中的靜態塊只在加載該類時運行一次。但它實際上意味着什麼?在哪一點上是由JVM(Java虛擬機)加載的類?「何時加載類」實際上意味着什麼?
是否在該類中的主要方法被調用時?並且是否在main方法開始執行時也加載了同一類的所有超類?
考慮到A擴展B和B擴展C.所有都有靜態塊。如果A有主要方法,那麼靜態塊的執行順序是什麼?
這在JLS的Execution部分進行了描述。即:
一類的初始化包括執行其靜態初始化和初始化在類中聲明靜態字段。接口的初始化包括爲接口中聲明的字段執行初始化程序。
在類初始化之前,它的直接超類必須初始化,但是類實現的接口不需要初始化。同樣,接口的超級接口在初始化之前不需要初始化。
因此,在您的示例中,「最上面」級(C
)的靜態塊先運行,那麼的B
,那麼最來源之一。
請參閱該文檔以獲取加載課程的所有步驟的詳細說明。
(當他們第一次主動使用類得到加載)
一類的初始化包括執行其靜態初始化和初始化靜態字段(類變量)在課堂上宣佈。接口的初始化包括執行在那裏聲明的字段(常量)的初始值設定項。
在類被初始化之前,它的父類必須被初始化,但類實現的接口沒有被初始化。類似地,接口的超級接口在接口初始化之前未被初始化。
該過程在Java Virtual Machine Specification中有更詳細的描述。
我覺得下面的例子將解決所有的問題,您:一類被初始化
之前,其超被初始化,如果他們以前沒有被初始化。
因此,測試程序:
class Super {
static { System.out.print("Super "); }
}
class One {
static { System.out.print("One "); }
}
class Two extends Super {
static { System.out.print("Two "); }
}
class Test {
public static void main(String[] args) {
One o = null;
Two t = new Two();
System.out.println((Object)o == (Object)t);
}
}
打印:
Super Two false
類之一是從來沒有被初始化,因爲它不使用主動,因此從不掛。只有在超類Super被初始化後,才能初始化類Two。
欲瞭解更多詳情,請訪問該link
編輯細節:刪除混亂線。
'就在JVM啓動後'並不是這個過程的準確描述。查看其他答案。 Downvote。 – EJP
消除那些令人困惑的線條 –