1.類加載
- 在java代碼中,類型的加載、連接與初始化過程都是在程序運行期間完成的。
- 提供了更大的靈活性,增加了更多的可能性。
2.Java虛擬機與程序的生命週期
如下幾種情況,虛擬機將結束生命週期:
- 執行了System.exist()
- 程序正常執行結束
- 程序執行過程中遇到了異常或錯誤而異常終止
- 由於操作系統出現錯誤而導致java虛擬機進程終止
3.對象的生命週期
(1) 加載:查找並加載類的二進制數據
說明:
將類的.class文件的二進制數據讀入到內存中,將其放在運行時數據的方法區內,然後在內存中創建一個java.lang.Class
用來封裝類在方法區內的數據結構(java規範並未說明Class對象位於哪裏HotSpot虛擬機將其放在方法區內)。
加載.class文件的方式:
- 從本地系統中直接加載
- 通過網絡下載.class文件
- 從zip、jar等歸檔文件中加載class文件
- 從專有的數據庫中提起class文件
- 將java源文件動態編譯爲class文件
(2) 連接階段:
- 驗證:確保加載類的正確性
- 準備:爲類的 靜態變量分配內存,並將其初始化爲 默認值
- 解析:把類中的符號引用轉換爲直接引用
(3)初始化:爲類的靜態變量賦予正確的初始值
- 所有的java虛擬機實現必須在每個類或者接口被java程序 首次主動使用纔會被初始化
(4)使用:程序代碼中的使用階段
- 主動使用
- 被動使用
(5)卸載: Class對象不在被引用時就會結束生命週期,類在方法區內的數據也會被卸載
主動使用和被動使用說明:
-
主動使用(7種):
(1)創建類的實例(putstatic)
(2)訪問某個類或者接口的靜態變量,或者對該靜態變量賦值(getstatic)
(3)調用類的靜態方法(invokestatic)
(4)反射,如:Class.forName("com.test.Test")
(5)初始化一個類的子類,標識是對該類的父類的主動使用
(6)Java虛擬機啓動時被標明爲啓動類的類(Main方法的類)
(7)JDK1.7開始提供的動態語言的支持:java.lang.invoke.MethodHandle
實例的解析結果GEF_GetStatic,REF_GETStatic,REF_InvokeStatic
句柄對應的類沒有初始化則初始化- 被動使用:
除了以上7種情況以外,其他使用java類的方式,都被看做是對類的被動使用,都不會導致類的初始化