當java程式首次通過下面6中方式來使用某個類或介面時,系統就會初始化該類或介面。
(1)建立類的執行個體。為某個類建立執行個體的方式包括:使用new操作符來建立執行個體,通過反射來建立執行個體,通過還原序列化的方式來建立執行個體。
(2)調用某個類的類方法(靜態方法)。
(3)訪問某個類變數或為某個類變數。或為該變數賦值
(4)使用反射方式來強制建立某個類或介面對應的java.lang.Class對象。例如:Class,forName("Person"),如果系統還未初始化Person類,則先初 始化Person類,然後返回Person類對應的java.lang.Class對象。
(5)初始化某個類的子類。子類的父類都會被初始化。
(6)直接使用java.exe命令運行某個主類,主類先被初始化。
注意:
對於一個final型的類變數,如果該變數的值在編譯期就可以確定下來,那麼這個類變數相當於“宏變數”,java編譯器會在編譯時間直接把這個類變數出現的地方全部替換為它的值。因此即使程式使用靜態變數,也不會導致該類的初始化。如下代碼將不會列印出靜態初始化塊
public class Test12 {static final String STRING="宏變數";static{System.out.println("靜態初始化塊");}}class Test13{public static void main(String[] args) {System.out.println(Test12.STRING);}}
反之,如果final修飾的類變數不能在編譯時間確定下來,則必須等到運行時才能確定該類變數的值,如果通過該類來訪問它的類變數,則會導致該類被初始化。 (下面的代碼將列印出靜態初始化快)
public class Test12 {static final String STRING=""+System.currentTimeMillis();static{System.out.println("靜態初始化塊");}}class Test13{public static void main(String[] args) {System.out.println(Test12.STRING);}