【Java 虚拟机原理】Android 类加载机制 ( 双亲委派机制 | BootClassLoader | PathClassLoader | DexClassLoader )
文章目錄
- 一、Android 類加載機(jī)制
- 二、雙親委派機(jī)制
一、Android 類加載機(jī)制
Android 中的類加載 使用了 雙親委派 機(jī)制 , 如下圖所示 :
在 Android 中提供了 333 個(gè)類加載器 , BootClassLoader , PathClassLoader , DexClassLoader ;
雙親委派機(jī)制 , 是 委派層級 上的 上下層級關(guān)系 , 并不是說 333 個(gè)類加載器 有 父子繼承關(guān)系 ;
類加載 的委派層級 : BootClassLoader -> PathClassLoader -> DexClassLoader ;
類加載器的繼承結(jié)構(gòu) : BootClassLoader 是父類 , PathClassLoader / DexClassLoader 是 BootClassLoader 的子類 ;
調(diào)用 DexClassLoader 進(jìn)行類加載 A 時(shí) , 進(jìn)行如下操作 :
① DexClassLoader 查詢 : 查詢自己是否加載過 A ;
- 如果加載過則不需要再進(jìn)行加載 ;
- 如果沒有加載過 , 則向上級 PathClassLoader 詢問 是否有加載過 A ;
② PathClassLoader 查詢 : 查詢自己是否加載過 A ;
- 如果加載過則不需要再進(jìn)行加載 ;
- 如果沒有加載過 , 則向上級 BootClassLoader 詢問 是否有加載過 A ;
③ BootClassLoader 查詢 : 查詢自己是否加載過 A ;
- 如果加載過則不需要再進(jìn)行加載 ;
- 如果沒有加載過 , 則 查詢自己是否可以加載 ;
④ BootClassLoader 查詢是否可以加載 :
- 如果自己可以加載 A , 則自己加載 ;
- 如果自己不可以加載 A , 則將加載任務(wù)委派給下級 PathClassLoader ;
⑤ PathClassLoader 查詢是否可以加載 :
- 如果自己可以加載 A , 則自己加載 ;
- 如果自己不可以加載 A , 則將加載任務(wù) 委派給下級 DexClassLoader ;
④ DexClassLoader 查詢是否可以加載 :
- 如果自己可以加載 A , 則自己加載 ;
- 如果自己不可以加載 A , 則 拋出 Class Not Found 異常 ;
整個(gè)過程就是 從下到上 詢問 , 然后 從上到下 委派 ;
二、雙親委派機(jī)制
類加載器層級 : 由高到低 : BootClassLoader -> PathClassLoader / DexClassLoader ;
雙親委派機(jī)制 :
自定義的類加載器 MyClassLoader 加載一個(gè) Class 類對象 Student , 可以 指定 parent 父類為 PathClassLoader , 該類會(huì) 向其上級父類 PathClassLoader 詢問該 Student 類對象 是否被加載過 , 如果沒有被加載過 ;
則繼續(xù)向 上級父類 BootClassLoader 詢問 Student 類對象 是否被加載過 , 如果被加載過 , 則返回類對象 , 如果沒有被加載過 , 則開始委派子類進(jìn)行加載 ;
BootClassLoader 委派子類 PathClassLoader 進(jìn)行加載 Student 類對象 , PathClassLoader 就會(huì)委派 MyClassLoader 進(jìn)行加載 , MyClassLoader 發(fā)現(xiàn)其沒有子類 , 則開始進(jìn)行類加載 Student 類對象 ;
在 ClassLoader 中的 loadClass 方法中 , 先調(diào)用了
// First, check if the class has already been loaded Class<?> c = findLoadedClass(name);方法 , 下檢查該類是否被加載過 , 如果沒有被加載過 , 則先判斷父類是否為空 , 如果不為空 , 則調(diào)用父類的 loadClass 方法 ,
if (parent != null) {c = parent.loadClass(name, false);} else {c = findBootstrapClassOrNull(name);}父類也調(diào)用父類的 loadClass 方法 , 如果調(diào)用到最頂層 , 沒有父類 , 則開始加載 ;
ClassLoader 類加載相關(guān)源碼 :
public abstract class ClassLoader {protected Class<?> loadClass(String name, boolean resolve)throws ClassNotFoundException{// First, check if the class has already been loadedClass<?> c = findLoadedClass(name);if (c == null) {try {if (parent != null) {c = parent.loadClass(name, false);} else {c = findBootstrapClassOrNull(name);}} catch (ClassNotFoundException e) {// ClassNotFoundException thrown if class not found// from the non-null parent class loader}if (c == null) {// If still not found, then invoke findClass in order// to find the class.c = findClass(name);}}return c;} }源碼參考 : /libcore/ojluni/src/main/java/java/lang/ClassLoader.java
《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的【Java 虚拟机原理】Android 类加载机制 ( 双亲委派机制 | BootClassLoader | PathClassLoader | DexClassLoader )的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Java 虚拟机原理】动态字节码技术
- 下一篇: 【Java 虚拟机原理】Java 类中的