三、類是如何被加載的?
三、類是如何被加載的?
什麽是類加載機制?
將.class中的二進制數據讀到內存,然後整理成類的元數據寫到方法區;然後根據類的元數據結構在堆內存中創建類的實例對象;
類的加載指的是將類的.class文件中的二進制數據讀入到內存中,將其放在運行時數據區的方法區內,然後在堆區創建一個java.lang.Class對象,用來封裝類在方法區內的類的數據結構。類的加載的最終產品是位於堆區中的Class對象,Class對象封裝了類在方法區內的數據結構,並且向Java程序員提供了訪問方法區內類的數據結構的接口。
加載時機
並非是首次使用時加載,JVM允許類加載器預先加載類;
如果在預先加載的過程中遇到了.class文件缺失或存在錯誤,類加載器必須在程序首次主動使用該類時報告錯誤(LinkageError錯誤)如果這個類一直沒有被程序主動使用,那麽類加載器就不會報告錯誤
加載.class的方式
加載.class文件的方式
1)從本地系統中直接加載
2)通過網絡下載.class文件
3)從zip,jar等歸檔文件中加載.class文件
4)從專有數據庫中提取.class文件
5)將Java源文件動態編譯為.class文件
類加載過程中做了什麽?
在加載階段,虛擬機需要完成以下三件事情:
1、通過一個類的全限定名來獲取其定義的二進制字節流。
2、將這個字節流所代表的靜態存儲結構轉化為方法區 類的運行時數據結構。
3、在Java堆中生成一個代表這個類的java.lang.Class對象,作為對方法區中這些數據的訪問入口。
加載階段完成後,虛擬機外部的 二進制字節流就按照虛擬機所需的格式存儲在方法區之中,而且在Java堆中也創建一個java.lang.Class類的對象,這樣便可以通過該對象訪問方法區中的這些數據。
類加載的方式-代碼
類加載有三種方式:
1、命令行啟動應用時候由JVM初始化加載
2、通過Class.forName()方法動態加載
3、通過ClassLoader.loadClass()方法動態加載
2和3的區別
Class.forName():將類的.class文件加載到jvm中之外,還會對類進行解釋,執行類中的static塊;
ClassLoader.loadClass():只幹一件事情,就是將.class文件加載到jvm中,不會執行static中的內容,只有在newInstance才會去執行static塊。
註:
Class.forName(name, initialize, loader)帶參函數也可控制是否加載static塊。並且只有調用了newInstance()方法采用調用構造函數,創建類的對象 。
什麽時候自定義類加載器?
有的時候,我們也需要自定義類加載器。比如應用是通過網絡來傳輸 Java 類的字節碼,為保證安全性,這些字節碼經過了加密處理,這時系統類加載器就無法對其進行加載,這樣則需要自定義類加載器來實現。自定義類加載器一般都是繼承自 ClassLoader 類,從上面對 loadClass 方法來分析來看,我們只需要重寫 findClass 方法即可。
參考文檔
http://www.cnblogs.com/ityouknow/p/5603287.html
三、類是如何被加載的?