2011-12-18 35 views
13

據說Java中的靜態塊只在加載該類時運行一次。但它實際上意味着什麼?在哪一點上是由JVM(Java虛擬機)加載的類?「何時加載類」實際上意味着什麼?

是否在該類中的主要方法被調用時?並且是否在main方法開始執行時也加載了同一類的所有超類?

考慮到A擴展B和B擴展C.所有都有靜態塊。如果A有主要方法,那麼靜態塊的執行順序是什麼?

回答

9

這在JLS的Execution部分進行了描述。即:

一類的初始化包括執行其靜態初始化和初始化在類中聲明靜態字段。接口的初始化包括爲接口中聲明的字段執行初始化程序。
在類初始化之前,它的直接超類必須初始化,但是類實現的接口不需要初始化。同樣,接口的超級接口在初始化之前不需要初始化。

因此,在您的示例中,「最上面」級(C)的靜態塊先運行,那麼的B,那麼最來源之一。

請參閱該文檔以獲取加載課程的所有步驟的詳細說明。

(當他們第一次主動使用類得到加載)

1

Java Language Specification

一類的初始化包括執行其靜態初始化和初始化靜態字段(類變量)在課堂上宣佈。接口的初始化包括執行在那裏聲明的字段(常量)的初始值設定項。

在類被初始化之前,它的父類必須被初始化,但類實現的接口沒有被初始化。類似地,接口的超級接口在接口初始化之前未被初始化。

該過程在Java Virtual Machine Specification中有更詳細的描述。

1

我覺得下面的例子將解決所有的問題,您:一類被初始化

之前,其超被初始化,如果他們以前沒有被初始化。

因此,測試程序:

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

編輯細節:刪除混亂線。

+0

'就在JVM啓動後'並不是這個過程的準確描述。查看其他答案。 Downvote。 – EJP

+0

消除那些令人困惑的線條 –

相關問題