java 類加載機制

Java類加載器的作用就是在運行時加載類。Java類加載器基於三個機制:委託、可見性和單一性。委託機制是指將加載一個類的請求交給父類加載器,如果這個父類加載器不能夠找到或者加載這個類,那麼再加載它。可見性的原理是子類的加載器可以看見所有的父類加載器加載的類,而父類加載器看不到子類加載器加載的類。單一性原理是指僅加載一個類一次,這是由委託機制確保子類加載器不會再次加載父類加載器加載過的類。正確理解類加載器能夠幫你解決NoClassDefFoundError和java.lang.ClassNotFoundException,因爲它們和類的加載相關。類加載器通常也是比較高級的Java面試中的重要考題,Java類加載器和工作原理以及classpath如何運作的經常被問到。Java面試題中也經常出現“一個類是否能被兩個不同類加載器加載”這樣的問題。這篇教程中,我們將學到類加載器是什麼,它的工作原理以及一些關於類加載器的知識點。

唯一性:對於任意一個類,必須類的加載器和類本身,同時來確立其唯一性,每一個類加載器,都擁有一個獨立的類的名稱空間。
 比較兩個類是否相等,只有在兩個類是由同一個類加載器加載的前提下才有意義,否則即使兩個類來源於同一個class 文件,被同一個虛擬機加載,只要加載器不同,那麼他們兩個類必定不同。這裏的“相等”包括對象的equals(),isAssignableForm(),isInstance 方法的返回結果。

http://greemranqq.iteye.com/blog/1994193

一個類是否能被兩個不同類加載器加載”答案應該是可以。


什麼是類加載器

類加載器是一個用來加載類文件的類。Java源代碼通過javac編譯器編譯成類文件。然後JVM來執行類文件中的字節碼來執行程序。類加載器負責加載文件系統、網絡或其他來源的類文件。有三種默認使用的類加載器:Bootstrap類加載器、Extension類加載器和System類加載器(或者叫作Application類加載器)。每種類加載器都有設定好從哪裏加載類。

  • Bootstrap類加載器負責加載rt.jar中的JDK類文件,它是所有類加載器的父加載器。Bootstrap類加載器沒有任何父類加載器,如果你調用String.class.getClassLoader(),會返回null,任何基於此的代碼會拋出NUllPointerException異常。Bootstrap加載器被稱爲初始類加載器。
  • 而Extension將加載類的請求先委託給它的父加載器,也就是Bootstrap,如果沒有成功加載的話,再從jre/lib/ext目錄下或者java.ext.dirs系統屬性定義的目錄下加載類。Extension加載器由sun.misc.Launcher$ExtClassLoader實現。
  • 第三種默認的加載器就是System類加載器(又叫作Application類加載器)了。它負責從classpath環境變量中加載某些應用相關的類,classpath環境變量通常由-classpath或-cp命令行選項來定義,或者是JAR中的Manifest的classpath屬性。Application類加載器是Extension類加載器的子加載器。通過sun.misc.Launcher$AppClassLoader實現。

除了Bootstrap類加載器是大部分由C來寫的,其他的類加載器都是通過java.lang.ClassLoader來實現的。

總結一下,下面是三種類加載器加載類文件的地方:

1) Bootstrap類加載器 – JRE/lib/rt.jar

2) Extension類加載器 – JRE/lib/ext或者java.ext.dirs指向的目錄

3) Application類加載器 – CLASSPATH環境變量, 由-classpath或-cp選項定義,或者是JAR中的Manifest的classpath屬性定義.



類加載器的工作原理

我之前已經提到過了,類加載器的工作原理基於三個機制:委託、可見性和單一性。這一節,我們來詳細看看這些規則,並用一個實例來理解工作原理。下面顯示的是類加載器使用委託機制的工作原理。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章