先要知道,瞭解類的載入機制有什麼用呢?
首先,可以控制JVM的行為,第二,可以讓程式能動態控制類載入,比如熱部署等,提高程式的靈活性和適應性。
類的載入就是把。java檔案編譯成。class檔案,然後載入到記憶體中的過程。
說到類載入,就不得不說配置jdk環境變數時用到的classpath了,通常我們的配置順序是:.;D:\Java\jdk6\lib\dt.jar;D:\Java\jdk6\lib\tools.jar,如果將這個順序改一下,那麼載入的順序也會發生變化。
JAVA中有三種類載入器:
1、Bootstrap Loader(啟動類載入器):載入System.getProperty("sun.boot.class.path")所指定的路徑或jar。2、Extended Loader(標準擴充類載入器ExtClassLoader):載入System.getProperty("java.ext.dirs")所指定的路徑或jar。在使用Java運行程式時,也可以指定其搜尋路徑,例如:java -Djava.ext.dirs=d:/projects/testproj/classes HelloWorld3、AppClass Loader(系統類別載入器AppClassLoader):載入System.getProperty("java.class.path")所指定的路徑或jar。在使用Java運行程式時,也可以加上-cp來覆蓋原有的Classpath設定,例如: java -cp ./lavasoft/classes HelloWorldExtClassLoader和AppClassLoader在JVM啟動後,會在JVM中儲存一份,並且在程式運行中無法改變其搜尋路徑。如果想在運行時從其他搜尋路徑載入類,就要產生新的類載入器。
JAVA載入時會從上到下依次載入,需要注意的是Bootstrap Loader(啟動類載入器)是最頂級的類載入器了,其父載入器為null.不過ext和boot也不是父子關係。因為boot是C實現的。
可以看這樣一個例子:
public static void main(String[] args){System.out.println(AAA.class.getName());System.out.println(AAA.class.getClassLoader());System.out.println(AAA.class.getClassLoader().getParent());System.out.println(AAA.class.getClassLoader().getParent().getParent());System.out.println(String.class.getClassLoader());}
輸出結果為:
com.AAAsun.misc.Launcher$AppClassLoader@18efd7csun.misc.Launcher$ExtClassLoader@a40f0enullnull
類的載入
類載入有三種方式:1、命令列啟動應用時候由JVM初始化載入2、通過Class.forName()方法動態載入3、通過ClassLoader.loadClass()方法動態載入三種方式區別比較大,看個例子就明白了:public class HelloWorld {
public staticvoid main(String[] args)
throws ClassNotFoundException {
ClassLoader loader = HelloWorld.class.getClassLoader();
System.out.println(loader);
//使用ClassLoader.loadClass()來載入類,不會執行初始化塊
loader.loadClass("Test2");
//使用Class.forName()來載入類,預設會執行初始化塊
// Class.forName("Test2");
//使用Class.forName()來載入類,並指定ClassLoader,初始化時不執行靜態塊
// Class.forName("Test2", false, loader);
}
}public class Test2 {
static {
System.out.println("靜態初始化塊執行了!");
}
}分別切換載入方式,會有不同的輸出結果。
有關ClassLoader還有很重要一點:同一個ClassLoader載入的類檔案,只有一個Class執行個體。但是,如果同一個類檔案被不同的ClassLoader載入,則會有兩份不同的ClassLoader執行個體(前提是著兩個類載入器不能用相同的父類載入器)。