⑴ java中類載入器是怎麼工作的
JVM將類載入過程分為三個步驟:裝載(Load),鏈接(Link)和初始化(Initialize)
鏈接又分為三個步驟,驗證、准備、解析
1) 裝載:查找並載入類的二進制數據;
2)鏈接:
驗證:確保被載入類的正確性;
准備:為類的靜態變數分配內存,並將其初始化為默認值;
解析:把類中的符號引用轉換為直接引用;
3)初始化:為類的靜態變數賦予正確的初始值;
那為什麼我要有驗證這一步驟呢?首先如果由編譯器生成的class文件,它肯定是符合JVM位元組碼格式的,但是萬一有高手自己寫一個class文件,讓JVM載入並運行,用於惡意用途,就不妙了,因此這個class文件要先過驗證這一關,不符合的話不會讓它繼續執行的,也是為了安全考慮吧。
准備階段和初始化階段看似有點牟盾,其實是不牟盾的,如果類中有語句:private static int a = 10,它的執行過程是這樣的,首先位元組碼文件被載入到內存後,先進行鏈接的驗證這一步驟,驗證通過後准備階段,給a分配內存,因為變數a是static的,所以此時a等於int類型的默認初始值0,即a=0,然後到解析(後面在說),到初始化這一步驟時,才把a的真正的值10賦給a,此時
⑵ java 中的class.forName()是什麼意思
Class.forName:返回與給定的字元串名稱相關聯類或介面的Class對象。
Class.forName是一個靜態方法,同樣可以用來載入類。該方法有兩種形式:Class.forName(String name, boolean initialize, ClassLoader loader)和Class.forName(String className)。第一種形式的參數name表示的是類的全名;initialize表示是否初始化類;loader表示載入時使用的類載入器。第二種形式則相當於設置了參數initialize的值為true,loader的值為當前類的類載入器。
如下圖所示,java類型的屬性名稱叫name,可以通過forName的方法獲取到這個類的實例,從而獲取到類裡面的屬性。
注意:
在指定類給 class.forName() 方法後,如果找不到指定的類,會拋出ClassNotFoundException異常。Class 的靜態 forName() 方法有兩個版本,上面的代碼是只指定類名稱的版本,而另一個版本可以讓你指定類名稱、載入時是否運行靜態區塊、指定類載入器:
Static Class forName(String name, boolean initialize, ClassLoader loader)
默認在載入類的時候,如果類中有定義靜態區塊則會運行它。你可以使用 class.forName() 的第二個版本,將initialize設定為 false,這樣在載入類時並不會立即運行靜態區塊,而會在使用類建立對象時才運行靜態區塊。為了印證,可以先設計一個測試類:
package cn.sunzn.demo;public class TestClass { static {
System.out.println("[運行靜態區塊]");
}
}