其實在Java中有許許多多的類加載器,我們甚至可以寫自己的類加載器。
其中主要三個類加載器(他們是樹形關系)是:
BootStrap:在java虛拟機啟動的時候會利用這個類加載器來加載 JDK安裝目錄下的 /JRE/LIB/rt.jar 也就是系統預設導入的一些類例如System類,這個類加載器不是類 。隻是作為一個java中類的起源工具。
ExpClassLoader:這個類加載器加載JDK安裝目錄下的/JRE/LIB/ext 目錄中的類 我們隻要把我們的類打包成JAR包放在這裡即可。
AppClassLoader:我們在java程式中classpath對應的類都有這個AppClassLoader導入進來。
看下面一段代碼:
package me.test;
/**
* BootStrap
* 加載 JRE/lib/rt.jar 包中的類 包括我們常用到的類
*
* ExtClassLoader
* 專門家在 JDK/JRE/libEXT/*.jar 中的類 隻要把我們的類放在這裡 就會被 這個加載器加載
*
* AppClassLoader
* 加載ClassPath指定的所有jar和目錄
* **/
public class Test1
{
public static void main(String []args)
{
System.out.println(Test1.class.getClassLoader().getClass().getName() ); //擷取主類的類加載器
System.out.println(System.class.getClassLoader());
//BootStrap 擷取System類的類加載器 因為加載器是 BootStrap是以傳回null 以為内他不是一個類
ClassLoader l=Test1.class.getClassLoader() ; //擷取Test1的類加載器
while(l!=null) //循環出 ClassLoader樹
{
System.out.println(l.getClass().getName());
l=l.getParent();
}
System.out.println(l);
}
}
ClassLoader的委托模型
比如說我們在加載一個類的時候AppClassLoader他先讓BootStrap來加載類,如果BootStrap已經加載了,那麼就傳回。如果找不到這個類那麼BootStrap就傳遞給ExtClassLoader 來查找,和BootStrap一樣。如果找到就加載,如果找不到就繼續傳遞給AppClassLoader 來加載。如果AppClassLoader還找不到的話,那麼AppClassLoader就會跑出ClassNotFoundException 異常。
我們為什麼不利用AppClassLoader下級的加載器呢?因為AppClassLoader下級可能有多個類加載器多個類加載器互相獨立,如果加載類那麼就會導緻記憶體中出現多份位元組碼,造成不必要的的記憶體浪費。這就是類加載器的委托模型。
本文出自seven的測試人生公衆号最新内容請見作者的GitHub頁:http://qaseven.github.io/