99插插插,亚洲伦理中文在线,站长推荐一二三区欧美,青青草在线导航

×

java 虛擬機(jī)10:類加載器

  • 作者:新網(wǎng)
  • 來源:新網(wǎng)
  • 瀏覽:100
  • 2018-04-23 14:33:28

虛擬機(jī)設(shè)計(jì)團(tuán)隊(duì)把類加載階段張的”通過一個(gè)類的全限定名來獲取此類的二進(jìn)制字節(jié)流”這個(gè)動(dòng)作放到Java虛擬機(jī)外部去實(shí)現(xiàn),以便讓應(yīng)用程序自己決定如何去獲取所需要的類。

   

  1a9e54a8-08e6-4532-9197-5b2e9bbd47ce.jpg

       虛擬機(jī)設(shè)計(jì)團(tuán)隊(duì)把類加載階段張的”通過一個(gè)類的全限定名來獲取此類的二進(jìn)制字節(jié)流”這個(gè)動(dòng)作放到Java虛擬機(jī)外部去實(shí)現(xiàn),以便讓應(yīng)用程序自己決定如何去獲取所需要的類。
       實(shí)現(xiàn)這個(gè)動(dòng)作的代碼模塊稱為”類加載器”。類加載器雖然只用于實(shí)現(xiàn)類的加載動(dòng)作,但它在Java程序中起到的作用卻遠(yuǎn)遠(yuǎn)不限定于類加載階段。對于任意一個(gè)類,都需要由加載它的類加載器和這個(gè)類本身一同確立其在Java虛擬機(jī)中的唯一性,每一個(gè)類加載器,都擁有一個(gè)獨(dú)立的類名稱空間。這句話表達(dá)地再簡單一點(diǎn)就是:比較兩個(gè)類是否”相等”,只有在這兩個(gè)類是由同一個(gè)類加載器加載的前提下才有意義,否則即使這兩個(gè)類來源于同一個(gè).class文件,被同一個(gè)虛擬機(jī)加載,只要加載它們的類加載器不同,這兩個(gè)類必定不相等。
  上面說的”相等”,包括代表類的.class對象的equals()方法、isAssignableFrom()方法、isInstance()方法的返回結(jié)果,也包括使用instanceof關(guān)鍵字做對象所屬關(guān)系判定等情況。
  類加載器模型
  從Java虛擬機(jī)的角度講,只有兩種不同的類加載器:啟動(dòng)類加載器Bootstrap ClassLoader,這個(gè)類加載器是由C++語言實(shí)現(xiàn)的,是虛擬機(jī)自身的一部分;其他類加載器,這些類加載器都由Java語言實(shí)現(xiàn),獨(dú)立于虛擬機(jī)外部,并且全部繼承自java.lang.ClassLoader。從開發(fā)人員的角度講,類加載器還可以劃分地更加細(xì)致一些,一張圖就能說明:
  關(guān)于這張圖首先說兩點(diǎn):
  1、這三個(gè)層次的類加載器并不是繼承關(guān)系,而只是層次上的定義
  2、它并不是一個(gè)強(qiáng)制性的約束模型,而是Java設(shè)計(jì)者推薦給開發(fā)者的一種類加載器實(shí)現(xiàn)方式
  OK,然后一個(gè)一個(gè)類加載器來看:
  1、啟動(dòng)類加載器Bootstrap ClassLoader
  之前說過了這是一個(gè)嵌在JVM內(nèi)核中的加載器。它負(fù)責(zé)加載的是JAVA_HOME/lib下的類庫,系統(tǒng)類加載器無法被Java程序直接應(yīng)用
  2、擴(kuò)展類加載器Extension ClassLoader
  這個(gè)類加載器由sun.misc.Launcher$ExtClassLoader實(shí)現(xiàn),它負(fù)責(zé)用于加載JAVA_HOME/lib/ext目錄中的,或者被java.ext.dirs系統(tǒng)變量指定所指定的路徑中所有類庫,開發(fā)者可以直接使用擴(kuò)展類加載器。java.ext.dirs系統(tǒng)變量所指定的路徑的可以通過程序來查看
  public class TestMain { public static void main(String[] args) { System.out.println(System.getProperty("java.ext.dirs")); } }
  運(yùn)行結(jié)果
  E:\\MyEclipse10\\Common\\binary\\com.sun.java.jdk.win32.x86_64_1.6.0.013\\jre\\lib\\ext;C:\\Windows\\Sun\\Java\\lib\\ext
  3、應(yīng)用程序類加載器Application ClassLoader
  這個(gè)類加載器由sun.misc.Launcher$AppClassLoader實(shí)現(xiàn)。這個(gè)類也一般被稱為系統(tǒng)類加載器,寫個(gè)小程序看下:
  public class TestMain { public static void main(String[] args) { System.out.println(ClassLoader.getSystemClassLoader()); } }
  運(yùn)行結(jié)果為:
  sun.misc.Launcher$AppClassLoader@546b97fd
  看到通過”ClassLoader.getSystemClassLoader”,得到的是sun.misc.Launcher$AppClassLoader,這也證明了JDK認(rèn)為Application ClassLoader是系統(tǒng)類加載器。順便根據(jù)類加載器模型,打印一下這個(gè)類的父加載器:
  public class TestMain { public static void main(String[] args) { System.out.println(ClassLoader.getSystemClassLoader().getParent()); } }
  運(yùn)行結(jié)果為:
  sun.misc.Launcher$ExtClassLoader@535ff48b
  看出Application ClassLoader的父加載器確實(shí)是Extension ClassLoader,符合圖中的模型。那么再打印父加載器呢?按照我們的想法應(yīng)該是Bootstrap ClassLoader了,看下是不是:
  public class TestMain { public static void main(String[] args) { System.out.println(ClassLoader.getSystemClassLoader().getParent().getParent()); } }
  運(yùn)行結(jié)果為:
  null
  這會(huì)打印出來的是null了。其實(shí)也很好理解,Bootstrap ClassLoader以外的ClassLoader都是Java實(shí)現(xiàn)的,因此這些ClassLoader勢必在Java堆中有一份實(shí)例在,所以Extension ClassLoader和Application ClassLoader都能打印出內(nèi)容來。但是Bootstrap ClassLoader是JVM的一部分,是用C/C++寫的,不屬于Java,自然在Java堆中也沒有自己的空間,所以就返回null了。所以,如果ClassLoader得到的是null,那么表示的ClassLoader就是Bootstrap ClassLoader。
  另外要說很重要的一點(diǎn),反編譯一下rt.jar,找到sun.misc.Launcher看一下Application ClassLoader的實(shí)現(xiàn):
  static class AppClassLoader extends URLClassLoader { public static ClassLoader getAppClassLoader(final ClassLoader paramClassLoader) throws IOException { String str = System.getProperty("java.class.path"); final File[] arrayOfFile = str == null ? new File[0] : Launcher.getClassPath(str); return (ClassLoader)AccessController.doPrivileged(new PrivilegedAction() { public Launcher.AppClassLoader run() { URL[] arrayOfURL = this.val$s == null ? new URL[0] : Launcher.pathToURLs(arrayOfFile); return new Launcher.AppClassLoader(arrayOfURL, paramClassLoader); } }); }
  重點(diǎn)就在第6行,Application ClassLoader只會(huì)加載java.class.path下的.class文件,java.class.path代表的是什么路徑?打印一下:
  public class TestMain { public static void main(String[] args) { System.out.println(System.getProperty("java.class.path")); } }
  運(yùn)行結(jié)果為:
  F:\\代碼\\MyEclipse\\TestArticle\\bin;F:\\學(xué)習(xí)\\第三方j(luò)ar包\\XStream\\xstream-1.4.jar;F:\\學(xué)習(xí)\\第三方j(luò)ar包\\XStream\\kxml2.jar
  Application ClassLoader只能加載項(xiàng)目bin目錄下的.class文件。雙親委派模型
  最后講一下雙親委派模型,其實(shí)上面的類加載器模型圖就是一個(gè)雙親委派模式的圖,這里把它再講清楚一點(diǎn)。
  雙親委派模型是在JDK1.2期間被引入的,其工作過程可以分為兩步:
  1、如果一個(gè)類加載器收到了類加載的請求,它首先不會(huì)自己去嘗試加載這個(gè)類,而是把這個(gè)請求委派給父類加載器去完成,每一個(gè)層次的類加載器都是如此。2、只有當(dāng)父加載器反饋?zhàn)约簾o法完成這這個(gè)加載請求(它的搜索范圍中沒有找到所需的類)時(shí),子加載器才會(huì)嘗試自己去加載
  所以,其實(shí)所有的加載請求最終都應(yīng)該傳送到頂層的啟動(dòng)類加載器中。雙親委派模型對于Java程序的穩(wěn)定運(yùn)作很重要,因?yàn)镴ava類隨著它的加載器一起具備了一種帶有優(yōu)先級的層次關(guān)系。例如java.lang.Object,存放于rt.jar中,無論哪一個(gè)類加載器要去加載這個(gè)類,最終都是由Bootstrap ClassLoader去加載,因此Object類在程序的各種類加載器環(huán)境中都是一個(gè)類。相反,如果沒有雙親委派模型,由各個(gè)類自己去加載的話,如果用戶自己編寫了一個(gè)java.lang.Object,并放在CLASSPATH下,那系統(tǒng)中將會(huì)出現(xiàn)多個(gè)不同的Object類,Java體系中最基礎(chǔ)的行為也將無法保證,應(yīng)用程序也將會(huì)變得一片混亂。
 

 

免責(zé)聲明:本文內(nèi)容由互聯(lián)網(wǎng)用戶自發(fā)貢獻(xiàn)自行上傳,本網(wǎng)站不擁有所有權(quán),也不承認(rèn)相關(guān)法律責(zé)任。如果您發(fā)現(xiàn)本社區(qū)中有涉嫌抄襲的內(nèi)容,請發(fā)送郵件至:operations@xinnet.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),本站將立刻刪除涉嫌侵權(quán)內(nèi)容。

免費(fèi)咨詢獲取折扣

Loading
怡红院欧美一区二区| 色呦呦se| 麻豆视频二区视频| 吃瓜中文字幕熟女| 性色AV一区二区三区免费看三| 99色中文字幕岛国电影| 亚洲日色| 五月丁香插逼| 抽插抽插爽| 欧美色XX无码产国韩曰清高新村 | 首页4k岛国视频一区二区| 亚洲五月天无码| 欧美麻豆新来的邻居| 久久久久九九大香蕉伊人| 日韩无码三四区| 91成人福利站| 八区精品人妻| 婷婷色五月天国产亚洲| 少妇被我操到高潮| 久久久中文字幕伦理午夜热门| 人人人人人人一区二区| 色色看主页| 成人日韩AV网址| 日韩Aⅴ一区、二区、三区| 国产 影院 麻豆| VA久AV久| 欧美精品一区二区三区′| 国产96精品久久久久久| 黄色成人在线小说| 天天射日韩欧美| 亚洲成人活塞运动在线| 91久久大香线蕉麻豆每日| 劲爆欧美伦理老熟女一区二区| 欧美日韩欧美日韩欧美| 国产欧美日韩草草柏芝| 国产精品普通话三区视频| 免费成人电影久久久| 亚洲射在线| 国产精品69电影免费观看| 欧美久久人精品| 国产日韩欧美五区成人在线观看|