JVM類加載機(jī)制詳解
一、先看看編寫出的代碼的執(zhí)行過程:

二、研究類加載機(jī)制的意義
從上圖可以看出,類加載是Java程序運行的第一步,研究類的加載有助于了解JVM執(zhí)行過程,并指導(dǎo)開發(fā)者采取更有效的措施配合程序執(zhí)行。
研究類加載機(jī)制的第二個目的是讓程序能動態(tài)的控制類加載,比如熱部署等,提高程序的靈活性和適應(yīng)性。
三、類加載的一般過程
原理:雙親委托模式
1、尋找jre目錄,尋找jvm.dll,并初始化JVM;
2、產(chǎn)生一個Bootstrap Loader(啟動類加載器);
3、Bootstrap Loader自動加載Extended Loader(標(biāo)準(zhǔn)擴(kuò)展類加載器),并將其父Loader設(shè)為Bootstrap Loader。
4、Bootstrap Loader自動加載AppClass Loader(系統(tǒng)類加載器),并將其父Loader設(shè)為Extended Loader。
5、最后由AppClass Loader加載HelloWorld類。
四、類加載器的特點
1、運行一個程序時,總是由AppClass Loader(系統(tǒng)類加載器)開始加載指定的類。
2、在加載類時,每個類加載器會將加載任務(wù)上交給其父,如果其父找不到,再由自己去加載。
3、Bootstrap Loader(啟動類加載器)是最頂級的類加載器了,其父加載器為null.
五、類加載器的獲取
很容易,看下面例子
public class HelloWorld {
public static void main(String[] args) {
HelloWorld hello = new HelloWorld();
Class c = hello.getClass();
ClassLoader loader = c.getClassLoader();
System.out.println(loader);
System.out.println(loader.getParent());
System.out.println(loader.getParent().getParent());
}
}
打印結(jié)果:
sun.misc.Launcher$AppClassLoader@19821f
sun.misc.Launcher$ExtClassLoader@addbf1
null
從上面的結(jié)果可以看出,并沒有獲取到ExtClassLoader的父Loader,原因是Bootstrap Loader(啟動類加載器)是用C語言實現(xiàn)的,找不到一個確定的返回父Loader的方式,于是就返回null。
六、類的加載
類加載有三種方式:
1、命令行啟動應(yīng)用時候由JVM初始化加載
2、通過Class.forName()方法動態(tài)加載
3、通過ClassLoader.loadClass()方法動態(tài)加載
三種方式區(qū)別比較大,看個例子就明白了:
package zhongqiu.common.base;
public class ClassLoadDemo {
static {
System.out.println("ClassLoadDemo靜態(tài)初始化塊執(zhí)行了!");
}
public static void main(String[] args) throws ClassNotFoundException {
ClassLoader loader2 = ClassLoadDemo.class.getClassLoader();
System.out.println(loader2);
// 使用ClassLoader.loadClass()來加載類,不會執(zhí)行初始化塊
// loader2.loadClass("zhongqiu.test.Test");
// 使用Class.forName()來加載類,默認(rèn)會執(zhí)行初始化塊
// Class.forName("zhongqiu.test.Test");
// 使用Class.forName()來加載類,并指定ClassLoader,初始化時不執(zhí)行靜態(tài)塊
Class.forName("zhongqiu.test.Test", false, loader2);
}
}
七、自定義ClassLoader
package zhongqiu.common.base.classload;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
public class MyClassLoader {
@SuppressWarnings("resource")
public static void main(String[] args)
throws MalformedURLException, ClassNotFoundException, IllegalAccessException, InstantiationException {
URL url = new URL("file:/D:/javaworkspace/JavaCommon/src/");
ClassLoader myloader = new URLClassLoader(new URL[] { url });
Class c = myloader.loadClass("zhongqiu.common.base.classload.Test");
Test t3 = (Test) c.newInstance();
}
}
在Java.lang包里有個ClassLoader類,ClassLoader 的基本目標(biāo)是對類的請求提供服務(wù),按需動態(tài)裝載類和資源,只有當(dāng)一個類要使用(使用new 關(guān)鍵字來實例化一個類)的時候,類加載器才會加載這個類并初始化。一個Java應(yīng)用程序可以使用不同類型的類加載器。例如Web Application Server中,Servlet的加載使用開發(fā)商自定義的類加載器, java.lang.String在使用JVM系統(tǒng)加載器,Bootstrap Class Loader,開發(fā)商定義的其他類則由AppClassLoader加載。在JVM里由類名和類加載器區(qū)別不同的Java類型。因此,JVM允許我們使用不同的加載器加載相同namespace的java類,而實際上這些相同namespace的java類可以是完全不同的類。這種機(jī)制可以保證JDK自帶的java.lang.String是唯一的。
八、為什么要使用這種雙親委托模式呢?
因為這樣可以避免重復(fù)加載,當(dāng)父親已經(jīng)加載了該類的時候,就沒有必要子ClassLoader再加載一次。
考慮到安全因素,我們試想一下,如果不使用這種委托模式,那我們就可以隨時使用自定義的String來動態(tài)替代java核心api中定義類型,這樣會存在非常大的安全隱患,而雙親委托的方式,就可以避免這種情況,因為String已經(jīng)在啟動時被加載,所以用戶自定義類是無法加載一個自定義的ClassLoader。
以上就是本文的全部內(nèi)容,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,同時也希望多多支持腳本之家!
相關(guān)文章
解決"XML Parser Error on line 1: 前言中不允許有內(nèi)容"錯誤
解決用windows自帶的記事編輯xml文件后出現(xiàn) "XML Parser Error on line 1: 前言中不允許有內(nèi)容。"的錯誤2018-02-02
Java中的runnable 和 callable 區(qū)別解析
Runnable接口用于定義不需要返回結(jié)果的任務(wù),而Callable接口可以返回結(jié)果并拋出異常,通常與Future結(jié)合使用,Runnable適用于簡單的后臺任務(wù)和定時任務(wù),而Callable適用于并行計算、異步操作和復(fù)雜任務(wù),選擇使用哪個接口取決于具體的應(yīng)用場景,感興趣的朋友一起看看吧2025-03-03
線程池ThreadPoolExecutor使用簡介與方法實例
今天小編就為大家分享一篇關(guān)于線程池ThreadPoolExecutor使用簡介與方法實例,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2019-03-03
Spring運行環(huán)境Environment的解析
本文主要介紹了Spring運行環(huán)境Environment的解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-08-08
深入淺析springsecurity入門登錄授權(quán)
SpringSecurity為我們提供了基于注解的權(quán)限控制方案,這也是我們項目中主要采用的方式,我們可以使用注解去指定訪問對應(yīng)的資源所需的權(quán)限,這篇文章主要介紹了springsecurity入門登錄授權(quán),需要的朋友可以參考下2024-05-05

