Java類載入機制的深入研究,java機制深入研究

來源:互聯網
上載者:User

Java類載入機制的深入研究,java機制深入研究
類載入機制

類載入是Java程式啟動並執行首要步驟,研究類的載入有助於瞭解JVM執行過程,並指導開發人員採取更有效措施配合程式執行,同時讓程式能動態控制類載入,比如熱部署等,提高程式的靈活性和適應性。

類載入過程

Java程式啟動並執行場所是記憶體。
當在命令列執行java HelloWorld的時候,JVM會將HelloWorld.class載入到記憶體中,形成一個class對象:HelloWorld.class,具體過程如下:
1.找到jre目錄,找到jvm.dll檔案,並且初始化JVM
2.產生一個Bootstrap Loader(引導程式,輕量級的應用程式,它定義了應用程式之間想要共用的類)
3.Bootstrap Loader自動載入Extended Loader(標準擴充類載入器),並將其父Loader設為Bootstrap Loader
4.Bootstrap Loader自動載入AppClass Loader(系統類別載入器),並將其父Loader設為Extended Loader。
5.最後由AppClass Loader載入HelloWorld類
Bootstrap Loader——>Extended Loader——>AppClass Loader
以上就是類載入的最一般的過程。

類載入器各自搜尋的目錄

1、Bootstrap Loader(啟動類載入器):載入System.getProperty(“sun.boot.class.path”)所指定的路徑或jar。

2、Extended Loader(標準擴充類載入器ExtClassLoader):載入System.getProperty(“java.ext.dirs”)所指定的路徑或jar。在使用Java運行程式時,也可以指定其搜尋路徑,例如:java -Djava.ext.dirs=d:\projects\testproj\classes HelloWorld

3、AppClass Loader(系統類別載入器AppClassLoader):載入System.getProperty(“java.class.path”)所指定的路徑或jar。在使用Java運行程式時,也可以加上-cp來覆蓋原有的Classpath設定,例如: java -cp ./lavasoft/classes HelloWorld

ExtClassLoader和AppClassLoader在JVM啟動後,會在JVM中儲存一份,並且在程式運行中無法改變其搜尋路徑。如果想在運行時從其他搜尋路徑載入類,就要產生新的類載入器。

類載入器的特點

1、運行一個程式時,總是由AppClass Loader(系統類別載入器)開始載入指定的類。
2、在載入類時,每個類載入器會將載入任務上交給其父,如果其父找不到,再由自己去載入。
3、Bootstrap Loader(啟動類載入器)是最頂級的類載入器了,其父載入器為null.

類載入器的擷取

看下面例子

public class HelloWorldClass {    public static void main(String[] args) {        HelloWorldClass hello = new HelloWorldClass();        Class c= hello.getClass();        ClassLoader loader = c.getClassLoader();        System.out.println("loader:"+loader);        System.out.println("loader.getParent():"+loader.getParent());        System.out.println("loader.getParent().getParent():"+loader.getParent().getParent());    }}

運行結果:

loader:sun.misc.Launcher$AppClassLoader@47415dbfloader.getParent():sun.misc.Launcher$ExtClassLoader@1471cb25loader.getParent().getParent():null

從上面的結果可以看出,並沒有擷取到ExtClassLoader的父Loader,原因是Bootstrap Loader(啟動類載入器)是用C語言實現的,找不到一個確定的返回父Loader的方式,於是就返回null。

類的載入

類載入有三種方式:
1、命令列啟動應用時候由JVM初始化載入
2、通過Class.forName()方法動態載入
3、通過ClassLoader.loadClass()方法動態載入
三種方式區別比較大,看個例子就明白了:

public class HelloWorld {         public static void main(String[] args) throws ClassNotFoundException {                 ClassLoader loader = HelloWorld.class.getClassLoader();                 System.out.println(loader);                 //使用ClassLoader.loadClass()來載入類,不會執行初始化塊                 loader.loadClass("Test2");                 //使用Class.forName()來載入類,預設會執行初始化塊 //                Class.forName("Test2");                 //使用Class.forName()來載入類,並指定ClassLoader,初始化時不執行靜態塊 //                Class.forName("Test2", false, loader);         } }public class Test2 {         static {                 System.out.println("靜態初始化塊執行了!");         } }

分別切換載入方式,會有不同的輸出結果。

自訂ClassLoader

為了說明問題,先看例子:

package test; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; /** * 自訂ClassLoader * * */ public class MyClassLoader {    public static void main(String[] args) throws MalformedURLException,            ClassNotFoundException, IllegalAccessException,            InstantiationException {        URL url = new URL(                "file:/E:\\projects\\testScanner\\out\\production\\testScanner");        ClassLoader myloader = new URLClassLoader(new URL[] { url });        Class c = myloader.loadClass("test.Test3");        System.out.println("----------");        Test3 t3 = (Test3) c.newInstance();    }}public class Test3 {    static {        System.out.println("Test3的靜態初始化塊執行了!");    }}
運行後:

Test3的靜態初始化塊執行了!

Process finished with exit code 0

可以看出自訂了ClassLoader myloader = new URLClassLoader(new URL[]{url});已經成功將類Test3載入到記憶體了,並通過預設構造方法構造了對象Test3 t3 = (Test3) c.newInstance();

有關ClassLoader還有很重要一點:
同一個ClassLoader載入的類檔案,只有一個Class執行個體。但是,如果同一個類檔案被不同的ClassLoader載入,則會有兩份不同的ClassLoader執行個體(前提是著兩個類載入器不能用相同的父類載入器)。

引用:
1.love_Javc_you的專欄:深入研究Java類載入機制
2.sysu_2010的專欄:BootStrap Loader

著作權聲明:本文為CSDN博主Lunatictwo原創文章,未經博主允許不得轉載。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.