Class類描述的是整個類的信息,在Class類中提供的forName()方法,這個方法根據ClassPath配置的路徑進行類的加載,如果說現在你的類加載路徑可能是網絡,文件,這個時候就必須實現類加載器,也就是ClassLoder類的主要作用。
什麼是ClassLoader
首先通過Class類觀察如下方法:
public ClassLoader getClassLoader()
我們來演示一個非常簡單的反射程序,來觀察ClassLoader的存在
package Loader;
class Member{}
public class TestDemo {
public static void main(String[] args) {
Class<?> cls=Member.class;
System.out.println(cls.getClassLoader());
System.out.println(cls.getClassLoader().getParent());
System.out.println(cls.getClassLoader().getParent().getParent());
}
}
我們來看一下我們的運行結果:
sun.misc.Launcher$AppClassLoader@18b4aac2
sun.misc.Launcher$ExtClassLoader@1540e19d
null
此時出現了了兩個類加載器:ExtClassLoader(擴展類加載器),AppClassLoader(應用程序類加載器)。
那麼,究竟什麼纔是我們的類加載器呢?
JVM設計團隊把類加載階段中的“通過一個類的全限定名來獲取描述此類的二進制字節流”這個動作放在java虛擬機外部去實現,以便讓應用程序自己決定如何去獲取所需要的類。實現這個動作的代碼模塊稱之爲“類加載器”。
JDK中內置的三大類加載器
Bootstarp(啓動類加載器):
- 使用C++實現,是JVM裏面的一部分
- 負責將存放於JAVA_HOME\lib目錄下的能被JVM識別的類庫加載到JVM中。(rt.jar存放了java所有基礎類庫,java.lang,java.util)
- 啓動類加載器,無法被java程序直接引用
ExtClassLoader(擴展類加載器): - 使用java實現,並且可以被java程序直接引用
- 加載JAVA_HOME\lib\ext目錄下能被識別的類庫
AppClassLoader(應用程序類加載器) - 負責加載用戶路徑(classPath)上指定的類庫
- 如果應用程序中沒有自定義的類加載器,則此加載器就是java程序中默認的類加載器。
雙親委派模型: - 定義:
1、 JDK內置的三種類加載器與用戶自定義類加載器之間的層次關係稱爲類加載器的雙親委派模型
2、要求除了頂層的父類加載器外,其餘的類加載器都應有自己的父類加載器
3、執行流程:如果一個類加載器收到了類加載請求,它首先不會自己去嘗試加載此類,而是把類加載請求委託給父類加載器完成,每一個層次類加載器均是如此。
只有當父類加載器無法完成加載請求時(在自己搜索範圍內沒有找到此類),子加載器纔會嘗試自己去加載
- 雙親委派模型的意義在於:
雙親委派模型保證了java程序的穩定運行。
Java中基礎類庫一定有頂層BootStrap類加載器加載,因此,諸如Object等核心類在各種類加載器環境下都是同一個類。
比較兩個類相等的前提:這兩個類必須是由同一個類加載器加載的前提下才有意義。
觀察我們的ClassLoader.loadClass()方法
我們在這裏不做深究,只需要知道,我們的類加載器是幹什麼的,它的主要是幫助我們的java程序得到穩定的運行。