1. 程式人生 > >三、類是如何被加載的?

三、類是如何被加載的?

clas 下載 進制 缺失 構造 事情 進制數 erro 對象

三、類是如何被加載的?

什麽是類加載機制?

將.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

三、類是如何被加載的?