深究一個靜態代碼塊不被執行問題

深究一個靜態代碼塊不被執行問題

問題現象:

  1. spring環境中的bean 的靜態代碼塊會被自動執行
  2. 工具類中的靜態代碼塊不被自動執行,工具類第一次被調用時靜態代碼塊執行
  3. 通過子類調用繼承的父類的方法,子類靜態代碼塊不被執行

複習ClassLoad

Java類加載 會初始化的情況有且僅有以下五種:(也稱爲主動引用)

1.遇到new(用new實例對象),getStatic(讀取一個靜態字段),putstatic(設置一個靜態字段),invokeStatic(調用一個類的靜態方法)這四條指令字節碼命令時

2.使用Java.lang.reflect包的方法對類進行反射調用時,如果此時類沒有進行init,會先init。

3.當初始化一個類時,如果其父類沒有進行初始化,先初始化父類

4.jvm啓動時,用戶需要指定一個執行的主類(包含main的類)虛擬機會先執行這個類

5.當使用JDK1.7的動態語言支持的時候,當java.lang.invoke.MethodHandler實例後的結果是REF-getStatic/REF_putstatic/REF_invokeStatic的句柄,並且這些句柄對應的類沒初始化的話應該首先初始

問題分析

  1. 工具類中的靜態代碼塊不被自動執行

    項目啓動時工具類不滿足Java類加載條件,因此未初始化,在第一次調用時,滿足Java類加載條件,ClassLoad同時執行靜態代碼塊

  2. 通過子類調用繼承的父類的方法,子類靜態代碼塊不被執行

    對應於Java類加載 第一條,invokeStatic的對象是父類,雖然是子類引用了父類方法,但是代碼的歸屬權上歸屬於父類,因此子類靜態代碼塊不執行(拓展子類引用父類靜態變量同理)

  3. 拓展問是不是在項目啓動時類一定會被加載到內存

    答案時否定的,使用時纔會加載。因此對性能要求較高情況需考慮啓動時全量加載。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章