結論及原因
- 結論:Java調用靜態方法時會對類進行裝載、連接和初始化
- 原因:Java類的加載方式是按需加載,遇到new、getstatic、putstatic或invokestatic這4條字節碼指令時,如果類沒有進行過初始化,則需要先觸發其初始化。生成這4條指令的最常見的Java代碼場景是:使用new關鍵字實例化對象的時候、讀取或設置一個類的靜態字段(被final修飾、已在編譯期把結果放入常量池的靜態字段除外)的時候,以及調用一個類的靜態方法的時候。
測試
-
參照之前寫的一篇文章,得出的測試思路:
- 對一個有靜態方法和靜態代碼塊的類只進行裝載,不進行初始化
- 通過反射獲取其靜態方法,並invoke這個靜態方法
- 因為靜態代碼塊在初始化的時候執行,所以如果invoke這個靜態方法的時候,靜態代碼塊執行了,說明了Java調用靜態方法時已經完成了類的初始化
-
有一個含有static方法和static塊的類
class MyStatic {
static {
System.out.println("靜態代碼塊執行了");
}
public static void say() {
System.out.println("靜態方法執行了");
}
MyStatic() {}
}
- 測試
public class Test {
Test() {}
public static void main(String[] args) {
Test test = new Test();
try{
Class clazz = Class.forName("MyStatic", false, test.getClass().getClassLoader());
Method method = clazz.getMethod("say");
method.invoke(null);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
-
控制台打印的結果:
靜態代碼塊執行了
靜態方法執行了
以上