classLoader類加載機制

本文系轉載,原文地址:http://shulianghan.iteye.com/blog/1699341

ClassLoader主要作用 :將.class後綴的字節碼文件從硬盤上裝載到內存中 ;

1.類加載器深入剖析

Java虛擬機與程序的生命週期 :
     當我們執行一個java程序的時候 , 會啓動一個JVM進程 , 當程序執行完之後 , JVM進程就消亡了; 
在如下情況下JVM將結束聲明週期 :

  • System.exit(int)方法 , 當執行這個方法的時候 , 虛擬機會退出 ; 這個方法傳入一個整形參數 , 這個參數是狀態嗎:  如果這個整形是 0 的話 , 就是正常退出 , 如果不是0的話 , 就是異常退出 ;
  • 程序正常結束;
  • 程序執行過程中 ,遇到了異常或錯誤 , 而異常終止 : 如果我們在程序中出現了異常 , 而不去處理 , 會將異常一直拋給main函數 ,main函數會將異常拋給JVM , JVM如果處理不了異常 , JVM就會異常退出 ;
  • 由於操作系統出現錯誤導致JVM進程終止 : JVM所依賴的平臺出現錯誤 , 導致JVM終止 ;

2.類的加載,連接和初始化

  • 加載 :查找並加載類的二進制數據 , 將class字節碼文件加載到內存中 ;
  • 連接 :

  •            -驗證 : 確保被加載的類的正確性 , 使用javac編譯工具生成的字節碼文件能通過驗證 , 如果不是由javac編譯生成的字節碼文件 ,如果自己生成的字節碼文件不符合JVM虛擬機對字節碼文件的要求的話 , 可能會出現驗證通不過的情況 ; 比如說隨便拿一個文件 , 將後綴名直接修改爲.class , 這樣的字節碼文件肯定不合法; 
               -準備 : 爲類的靜態變量分配內存 , 並將其初始化爲默認值; 
               -解析 : 把類中的符號引用轉爲直接引用 ;
  • 初始化  :爲類的靜態變量賦予正確的初始值(正確的值指的是用戶賦的值) ;
  •            -好像這個與連接階段的準備有些重複 , 在連接的準備階段只是賦予初始變量 , 如果用戶給這個變量賦了初始值 ,那麼這個變量在連接的準備階段仍然會賦予初始值 ; 
               -在這個階段 , 纔會真正的將初始值賦給靜態變量 ; 

Java程序對類的使用方式有 主動使用 和被動使用 
     所有的JVM實現 , 必須在每個類或者接口 , 被java程序 “首次主動使用” 時才初始化他們; 
主動使用 :

  •  創建類的實例 ;
  •  訪問某個類或接口的靜態變量 , 或者對該靜態變量賦值 ;
  •  調用類的靜態方法 ;
  •  反射 : Class.forName(“類名”) ;
  •  初始化一個類的子類 , 看做對父類的主動使用 ; 
  •  java虛擬機啓動的時候 , 被標明啓動類的類 , 即包含main方法的類 , 程序的入口;


     除了上面6種主動使用之外 , 其它的情況均爲被動使用 , 其它情況都不會執行第三步初始化 ;

 

3.類的加載

(1)概念

 

  • 類的加載 : 指的是將類的.class文件中的二進制數據讀入到內存 , 將其放在運行時數據區的方法區 , 然後再堆區創建一個java.lang.Class對象 , 用來封裝類在方法區內的數據結構 ;
  • 反射 : 反射就是跟句堆區的字節碼文件 , 獲取方法去的數據結構 ;
  • 解析 : Class對象是由JVM自己創建的 , 所有的對象都是經過Class對象創建 , 這個Class對象是反射的入口通過Class對象 , 可以關聯到目標class字節碼文件的內部結構 ;

 

    所有的類對應的Class對象都是唯一的一個 , 這個類是由JVM進行創建的 , 並且只有JVM纔會創建Class對象

 


類加載的最終產品是位於堆區中的Class對象 ,Class對象封裝了類在方法區內的數據結構 , 並且向Java程序員提供了訪問方法區內的數據結構的接口(反射用的接口) ;

 

 

(2)加載.class文件的方式

從本地系統中直接加載 : 編譯好的.class字節碼文件直接從硬盤中加載 ;

通過網絡下載.class文件 : class字節碼文件放在網絡空間中 , 使用URLClassLoader來加載在網絡上的.class字節碼文件 , 使用默認的父親委託機制加載字節碼文件 ;

zip ,jar 等壓縮文件中加載字節碼文件 : 在開發的時候 , 導入jar , 就是這種方式 ;

從專有的數據庫中提取字節碼文件 ;

java源文件動態編譯爲字節碼文件 ;

 

(3)類加載器

  l  Java虛擬機自帶的類加載器 :

    -根類加載器 ( Bootstrap ): 是C++寫的 , 程序員無法再方法獲取到的是一個null值 ;

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