ClassLoader雙親委派模式作用詳解
前言
我們的面試中經(jīng)常會(huì)遇到關(guān)于ClassLoader的問題,但是我們的日常開發(fā)中又沒有直接編寫過ClassLoader相關(guān)的代碼。對于小白新手來說,可能都不知道ClassLoader是用來干嘛的,它是如何在無形當(dāng)中影響我們編寫的代碼的?
ClassLoader的作用
見名知意,ClassLoader就是類加載器,它的作用就是將我們編寫的java代碼加載到JVM虛擬機(jī)中。在JVM啟動(dòng)的時(shí)候是不會(huì)一次性把所有的java類加載進(jìn)去的,而是在需要的時(shí)候才加載指定的類文件,要不然類特別多的話,大部分類一時(shí)用不上,那就浪費(fèi)內(nèi)存資源了。既然ClassLoader是用來加載類文件的,那么我們平時(shí)寫的java代碼是如何加載的呢?
ClassLoader的種類
在JDK中,默認(rèn)是有三種ClassLoader的:
Bootstrap ClassLoader
主要加載核心類庫,加載${JRE_HOME}/lib下的rt.jar、resources.jar等;
Extension ClassLoader
加載擴(kuò)展類庫,加載${JRE_HOME}/lib/ext文件夾下的jar包和class文件;
另外還會(huì)加載-D java.ext.dirs指定的目錄下的jar包和class文件;
AppClassLoader
加載當(dāng)前應(yīng)用classpath下的所有class文件;
如何實(shí)現(xiàn)雙親委派模式
在Launcher類中,我們可以看到Launcher創(chuàng)建的時(shí)候,同時(shí)創(chuàng)建了ExrClassLoader與AppClassLoader對象。
sun.misc.Launcher:
public Launcher() {
Launcher.ExtClassLoader var1;
try {
var1 = Launcher.ExtClassLoader.getExtClassLoader();
} catch (IOException var10) {
throw new InternalError("Could not create extension class loader", var10);
}
try {
this.loader = Launcher.AppClassLoader.getAppClassLoader(var1);
} catch (IOException var9) {
throw new InternalError("Could not create application class loader", var9);
}
Thread.currentThread().setContextClassLoader(this.loader);
}
1.創(chuàng)建ExtClassLoader對象;
2.創(chuàng)建AppClassLoader對象,并把ExtClassLoader對象作為AppClassLoader的父級ClassLoader;
3.把AppClassLoader對象綁定到線程上下文中;
為什么沒有提到BoostrapClassLoader?
因?yàn)锽oostrapClassLoader在java層面是拿不到的,ExtClassLoader的父級ClassLoader就是BoostrapClassLoader,java層面取出來就是null;
為了了解清楚類的加載方式,我們首先需要從AppClassLoader中的loadClass()方法中入手:
protected Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException
{
synchronized (getClassLoadingLock(name)) {
// 首先, 檢查這個(gè)類是否已經(jīng)加載好了
Class<?> c = findLoadedClass(name);
// 如果沒有加載過
if (c == null) {
long t0 = System.nanoTime();
try {
// 如果父級ClassLoader不為空,那么就先嘗試讓父級ClassLoader加載
if (parent != null) {
c = parent.loadClass(name, false);
} else {
// 如果父級ClassLoader為空,有可能父級ClassLoader是BootstrapClassLoader,那么先嘗試在BootstrapClassLoader加載
c = findBootstrapClassOrNull(name);
}
} catch (ClassNotFoundException e) {
// ClassNotFoundException thrown if class not found
// from the non-null parent class loader
}
// 如果一直向上都沒有加載目標(biāo)class,那么最終回到當(dāng)前ClassLoader加載
if (c == null) {
// If still not found, then invoke findClass in order
// to find the class.
long t1 = System.nanoTime();
c = findClass(name);
// this is the defining class loader; record the stats
sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
sun.misc.PerfCounter.getFindClasses().increment();
}
}
if (resolve) {
resolveClass(c);
}
// 返回加載成功的類
return c;
}
}
通過以上代碼分析,我們可以大概了解到雙親委派模式了:
1.先在當(dāng)前ClassLoader檢查是否已經(jīng)加載了目標(biāo)類;
2.如果當(dāng)前ClassLoader沒有加載目標(biāo)類,那么先向嘗試讓父級ClassLoader加載目標(biāo)類,直至BootstrapClassLoader;
3.如果最終所有的父級ClassLoader都沒有加載目標(biāo)類,那么當(dāng)前ClassLoader嘗試自己加載目標(biāo)類;
4.所有父級ClassLoader重復(fù)操作1~3步驟;
5.只要其中任意一個(gè)ClassLoader成功加載目標(biāo)類,那么就直接返回;
小測試
為了驗(yàn)證小伙伴們是否已經(jīng)明白了雙親委派模式,我們出一個(gè)小小的測試題留給大家:
我們通過自己創(chuàng)建一個(gè)java.lang.String的類(類名和包名和JDK中的String.class一致),這個(gè)自定義的String類能不能通過AppClassLoader成功地加載到JVM中?
以上就是ClassLoader雙親委派模式作用詳解的詳細(xì)內(nèi)容,更多關(guān)于ClassLoader雙親委派模式的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
SpringBoot+MyBatis簡單數(shù)據(jù)訪問應(yīng)用的實(shí)例代碼
這篇文章主要介紹了SpringBoot+MyBatis簡單數(shù)據(jù)訪問應(yīng)用的實(shí)例代碼,需要的朋友可以參考下2017-05-05
功能強(qiáng)大的TraceId?搭配?ELK使用詳解
這篇文章主要為大家介紹了功能強(qiáng)大的TraceId?搭配?ELK使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09
java中JDBC實(shí)現(xiàn)往MySQL插入百萬級數(shù)據(jù)的實(shí)例代碼
這篇文章主要介紹了java中JDBC實(shí)現(xiàn)往MySQL插入百萬級數(shù)據(jù)的實(shí)例代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-01-01
使用 Spring Boot 2.0 + WebFlux 實(shí)現(xiàn) RESTful API功能
什么是 Spring WebFlux, 它是一種異步的, 非阻塞的, 支持背壓(Back pressure)機(jī)制的Web 開發(fā)框架.下面通過本文給大家介紹使用 Spring Boot 2.0 + WebFlux 實(shí)現(xiàn) RESTful API功能,需要的朋友參考下吧2018-01-01
Springboot項(xiàng)目刪除項(xiàng)目同步target文件問題解決方案
這篇文章主要介紹了Springboot項(xiàng)目刪除項(xiàng)目同步target文件問題解決方案,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-12-12

