日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

淺談Java自定義類加載器及JVM自帶的類加載器之間的交互關系

瀏覽:80日期:2022-08-16 13:54:20
JVM自帶的類加載器:

淺談Java自定義類加載器及JVM自帶的類加載器之間的交互關系

其關系如下:

淺談Java自定義類加載器及JVM自帶的類加載器之間的交互關系

其中,類加載器在加載類的時候是使用了所謂的“父委托”機制。其中,除了根類加載器以外,其他的類加載器都有且只有一個父類加載器。

關于父委托機制的說明:

淺談Java自定義類加載器及JVM自帶的類加載器之間的交互關系

當生成 一個自定義的類加載器實例時,如果沒有指定它的父加載器,那么系統類加載器將成為該類加載器的父類加載器

下面,自定義類加載器。自定義的類加載器必須繼承java.lang.ClassLoader類

import java.io.*;public class MyClassLoader extends ClassLoader { private String name; //類加載器的名字 private String path; //加載類的路徑 private final String fileType = '.class'; //class文件的擴展名 public MyClassLoader(String name){ super(); //讓系統類加載器成為該類加載器的父 類加載器,該句可省略不寫 this.name = name; } public MyClassLoader(ClassLoader parent,String name){ super(parent); //顯示指定該類加載器的父 類加載器 this.name = name; } @Override public String toString() { return this.name; } public String getPath() { return path; } public void setPath(String path) { this.path = path; } //實現自定義的類加載器必須重寫findClass方法,否則ClassLoader類中的findClass()方法是拋出了異常 @Override public Class findClass(String name)throws ClassNotFoundException{ byte[] data = this.loadClassData(name); return this.defineClass(name,data,0,data.length); } private byte[] loadClassData(String name){ InputStream is = null; byte[] data = null; ByteArrayOutputStream baos = null; try { this.name = this.name.replace('.',''); //com.dream.it---->comdreamit is = new FileInputStream(new File(path + name + fileType)); int ch; while(-1 != (ch = is.read())){baos.write(ch); //將數據寫入到字節數組輸出流對象中去 } data = baos.toByteArray(); } catch (Exception e) { e.printStackTrace(); }finally { try {is.close();baos.close(); } catch (IOException e) {e.printStackTrace(); } } return data; } public static void main(String[] args) throws Exception { MyClassLoader loader1 = new MyClassLoader('loader1'); loader1.setPath('d:/myapp/serverlib/'); MyClassLoader loader2 = new MyClassLoader(loader1,'loader2'); //loader1作為loader2的父 類加載器 loader2.setPath('d:/myapp/clientlib'); MyClassLoader loader3 = new MyClassLoader(null,'loader3');//父類加載器為null,表明其父類加載器為根類加載器 loader3.setPath('d:/myapp/otherlib'); test(loader2); test(loader3); } public static void test(ClassLoader cl) throws Exception { Class clazz = cl.loadClass('Sample'); Object object = clazz.newInstance(); }}附上findClass()方法的JDK說明

protected Class<?> findClass(String name) throws ClassNotFoundExceptionFinds the class with the specified binary name. This method should be overridden by class loaderimplementations that follow the delegation model for loading classes, and will be invoked by the loadClass method after checking the parent classloader for the requested class. The default implementation throws a ClassNotFoundException.

大致說明一下意思:通過指定的name來查找類。該方法應該被類加載器的實現類重寫,從而能夠保證在加載類的時候可以遵循委托機制模型。在loadClass()方法(該方法是由JVM調用的)中,檢查其父類加載器之后,該方法再被調用去加載請求的類。默認該方法的實現是拋出了一個ClassNotFoundException異常。

其實,所謂的加載類,無非就是讀取.class文件到內存中,所以在findClass()方法中,loadClassData()方法用于讀取.class文件的數據,并返回一個字節數組。然后利用ClassLoader類的defineClass()方法將字節數組轉換為Class對象。

上述自定義的類加載器loader1,loader2,loader3及JVM自帶的類加載器之間的關系如下:

淺談Java自定義類加載器及JVM自帶的類加載器之間的交互關系

對于各個類加載器,系統的類加載器是從環境變量classpath中讀取.class文件實現類的加載;loader1是從目錄d:/myapp/serverlib/下讀取.class文件;loader2是從目錄d:/myapp/clientlib/下讀取.class文件,loader3是從目錄d:/myapp/otherlib/下讀取.class文件

執行結果:

淺談Java自定義類加載器及JVM自帶的類加載器之間的交互關系

此處我們分析一下出現這種執行結果的原因:

當執行loader2.loadClass(“Sample”)時先由它上層的所有父類加載器嘗試加載Sample類。

loader1從D:myappserverliv目錄下成功加載了Sample類,所以loader1是Sample類的定義類加載器,loader1和loader2是Sample類的初始類加載器。

當執行loader3.loadClass(“Sample”)時,先由它上層的所有父類加載器嘗試加載Sample類。

loader3的父加載器為根類加載器,它無法加載Sample類,接著loader3從D:myappotherlib目錄下成功加載Sample類,所以loader3是Sample類的定義類加載器及初始類加載器。

在Sample類中主動使用了Dog類(new Dog()),當執行Sample類的構造方法中的new Dog()語句時,JVM需要先加載Dog類,到底用哪個類加載器家在呢?

從上述的打印結果中可以看出,加載Sample類的loader1還加載了Dog類,JVM會用Sample類的定義類加載器去加載Dog類,加載過程中也同樣采用了父親委托機制。

為了驗證這一點,可以吧D:myappserverlib目錄下Dog.class文件刪除,然后在D:myappsyslib目錄下存放一個Dog.class文件,此時打印結果如下:

Sample:loader1Dog:sun.misc.Launcher$AppClassLoader@1b84c92Sample:loader3Dog:loader3

由此可見,當由loader1加載的Sample類首次主動使用Dog類時,Dog類由系統類加載器加載,如果把D:myappserverlib和D:myappsyslib目錄下的Dog.class文件都刪除,然后在D:myappclient目錄下存放一個Dog.class文件。

此時文件結構如下圖所示:

淺談Java自定義類加載器及JVM自帶的類加載器之間的交互關系

當Loader1加載Sample類首次主動使用Dog類時,由于loader1及其父類加載器都無法加載Dog類,因此test(loader2)會拋出ClassNotFoundExcption.

這又是因為什么原因呢?

這又牽扯到命名空間的問題。

同一個命名空間內的類時相互可見的。

子加載器的命名空間包含所有父類加載器的命名空間,因此由子加載器加載的類能看見父類加載器加載的類。例如系統類加載器加載的類能看見根類加載器加載的類。由父加載器加載的類不能看見子加載器加載的類。

如果兩個加載器之間沒有直接或間接的父子關系,那么它們各自加載的類相互不可見。

對于上述問題,loader1可以加載Sample類,而Dog類只能由loader2加載Dog類,loader1是Loader2的父類加載器,父加載器loader1加載的類Sample不能看見子加載器loader2加載的類Dog,所以會拋出異常。

對于上述實例中的main方法,我們不調用test方法,換成如下代碼

Class clazz = loader1.loadClass('Sample');Object obj = clazz.newInstance();Sample sample = (Sample)obj;System.out.println(sample.v1);

MyClassLoader類由系統類加載器加載,而Sample類由loader1類加載器加載,所以MyClassLoader類看不見Sample類。在MyClassLoader類的main方法中使用Sample類,會導致NoClassFoundError錯誤。

當兩個不同命名空間內的類相互不可見時,可采用Java反射機制來訪問對象實例的屬性和方法。

將上述代碼修改:

Class clazz = loader1.loadClass('Sample');Object obj = clazz.newInstance();Field field = clazz.getField('v1');int v1 = field.getInt(obj);System.out.println(v1);

此時,可以獲取到對象中的v1屬性值。利用反射機制,我們可以跨越這種命名空間的限制。

補充:

命名空間:

淺談Java自定義類加載器及JVM自帶的類加載器之間的交互關系

運行時包:

淺談Java自定義類加載器及JVM自帶的類加載器之間的交互關系

以上為個人經驗,希望能給大家一個參考,也希望大家多多支持好吧啦網。如有錯誤或未考慮完全的地方,望不吝賜教。

標簽: Java
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
国产精品3区| 国产精品久久久免费| 亚洲少妇一区| 国产成人久久精品麻豆二区 | 日韩一区二区三区免费视频| 久久精品主播| 国产96在线亚洲| 国产精品一区二区三区av麻| 日韩中文字幕亚洲一区二区va在线 | 日韩中出av| 亚洲一二av| 亚洲精品伊人| 日韩中文字幕在线一区| 在线亚洲成人| 99久久亚洲精品蜜臀| 日韩欧美二区| 久久中文字幕av| 国产一区白浆| 亚洲18在线| 免费精品视频| 欧美亚洲综合视频| 国产精品九九| 欧美aa在线观看| 国产精品嫩草99av在线| 色综合视频一区二区三区日韩| 久久高清免费| 亚洲影院天堂中文av色| 久久国产生活片100| 精品一区二区三区中文字幕视频 | 麻豆国产一区| 不卡一二三区| 亚洲女同中文字幕| 日韩美女精品| 精品高清久久| 免费视频亚洲| 日本vs亚洲vs韩国一区三区二区| 国产精品色在线网站| 韩日一区二区| 国产精品日韩久久久| 日韩av字幕| 中文字幕在线高清| 四虎4545www国产精品 | 日本激情一区| 午夜久久黄色| 国产欧美一区二区精品久久久 | 91久久国产| 69堂精品视频在线播放| 午夜久久中文| 亚洲制服欧美另类| 精品国产亚洲日本| 亚洲1234区| 日韩欧美不卡| 日本精品另类| 欧洲精品一区二区三区| 免费日本视频一区| 精品视频自拍| 合欧美一区二区三区| 国产日韩免费| 欧美+亚洲+精品+三区| 欧美亚洲免费| 国产精品99免费看| 国产精品sm| 亚洲色诱最新| 视频在线不卡免费观看| 免费成人在线影院| 国产精品一区二区99| 九色精品91| 美女在线视频一区| 综合亚洲视频| 欧美sss在线视频| 国产免费av国片精品草莓男男| 成人羞羞在线观看网站| 亚洲精品无播放器在线播放| 青青青免费在线视频| 日韩激情中文字幕| 99精品视频在线观看免费播放| 日本麻豆一区二区三区视频| 999久久久免费精品国产| 国产调教精品| 国产精品日本| 国产自产自拍视频在线观看| 亚洲3区在线| 性欧美69xoxoxoxo| 国产成人精品福利| 日本免费新一区视频| 国产综合欧美| 成人午夜在线| 欧美日韩亚洲一区二区三区在线| 成人av动漫在线观看| 成人一区不卡| 久久av导航| 日本不卡的三区四区五区| 性欧美xxxx免费岛国不卡电影| 久久精品国产精品亚洲毛片| 日韩午夜视频在线| 不卡av一区二区| 日韩久久电影| 国产精品嫩草影院在线看| 视频在线观看一区| 米奇777超碰欧美日韩亚洲| 国产精品成久久久久| 国产精品久久久一区二区| 日韩一区二区三免费高清在线观看| 99国产精品| 在线日韩一区| 青青青免费在线视频| 精品国产美女a久久9999| 7m精品国产导航在线| 中文不卡在线| 丝袜a∨在线一区二区三区不卡| 日本精品在线中文字幕| 国模大尺度视频一区二区| 国产精品一线| 日韩av午夜在线观看| 日韩中文字幕1| 欧美专区18| 99国内精品| 伊人成人网在线看| 欧美/亚洲一区| 国产一区观看| 亚洲性视频h| 欧美/亚洲一区| 精品日韩毛片| 亚洲精品va| 在线亚洲成人| 亚洲一区观看| 三级在线观看一区二区| 一区二区三区四区在线观看国产日韩| 乱人伦精品视频在线观看| 丝袜美腿成人在线| 日韩区欧美区| 国产毛片精品久久| 欧美1区2区3| 国产videos久久| 欧美香蕉视频| 免费国产自久久久久三四区久久 | 日韩国产一二三区| 欧美在线日韩| 久久精品福利| 国产v日韩v欧美v| 日韩在线看片| 91精品观看| 综合亚洲自拍| 国产精久久一区二区| 日本一区二区免费高清| 久久美女性网| 西西人体一区二区| 日本成人精品| 国产成人77亚洲精品www| 日韩在线免费| 午夜影院欧美| 视频一区中文字幕精品| 国产精品亚洲欧美日韩一区在线 | 日韩综合一区二区三区| 日本aⅴ免费视频一区二区三区| 日韩av黄色在线| 日本一区二区免费高清| 欧美日韩在线网站| 三级一区在线视频先锋| 欧美一级二区| 日本精品黄色| 亚洲成人免费| 日韩欧美高清一区二区三区| 麻豆精品视频在线| 久久久久久久久99精品大| 老色鬼久久亚洲一区二区| 国产亚洲精aa在线看| 久久中文精品| 亚洲午夜一级| 日韩精品导航| 激情国产在线| 午夜在线视频观看日韩17c| 国产日韩欧美高清免费| 黄色在线网站噜噜噜| 免播放器亚洲| 国产精品欧美大片| 久久精品99久久无色码中文字幕| 欧美女激情福利| 91精品国产自产观看在线| 国产精品99视频| 中文字幕一区二区三区在线视频| 精品视频亚洲| 另类亚洲自拍| 欧美好骚综合网| 亚洲欧洲美洲国产香蕉| 日产精品一区二区| 亚洲最新av| 亚洲综合在线电影| 日韩av中文字幕一区二区三区| 日韩精品dvd| 久久国产日韩欧美精品| 欧美一级精品| 日本不卡不码高清免费观看| 超碰超碰人人人人精品| 亚洲精品极品| 91日韩在线| 日韩综合一区二区三区| 天堂日韩电影| 97精品资源在线观看| 国产亚洲一区二区手机在线观看|