posts - 14,  comments - 37,  trackbacks - 0
          JavaClassLoaderPackage機制介紹了ClassLoader的委派機制,它是把裝載的任務傳遞給上級的裝載器的,依次類推,直到啟動類裝載器(沒有上級類裝載器)。如果啟動類裝載器能夠裝載這個類,那么它會首先裝載。如果不能,則往下傳遞。其實這引出一個運行時包的概念。不同裝載器裝載的類,即使包名相同也不能互相訪問。這樣保證了核心類庫不被破壞。(by juxtapose)

          本文將講述如何擴展ClassLoader類實現一個自己的類裝載器,每個Class對象都有一個引用指向裝載他的ClassLoader,你可以通過public ClassLoader getClassLoader()方法得到它。為了創建自己的類裝載器我們應該擴展ClassLoader類,這是一個抽象類。我們目的是從本地文件系統使用我們實現的類裝載器裝載一個類。我們創建一個FileClassLoader extends ClassLoader。我們需要覆蓋ClassLoader中的
          findClass(String name)
          方法,這個方法通過類的名字而得到一個Class對象。

          1public Class findClass(String name)
          2{
          3byte[] data = loadClassData(name);
          4return defineClass(name, data, 0, data.length);
          5}

          6


          我們還應該提供一個方法loadClassData(String name),通過類的名稱返回class文件的字節數組。然后使用ClassLoader提供的defineClass()方法我們就可以返回Class對象了。

           1public byte[] loadClassData(String name)
           2{
           3FileInputStream fis = null;
           4byte[] data = null;
           5try
           6{
           7fis = new FileInputStream(new File(drive + name + fileType));
           8ByteArrayOutputStream baos = new ByteArrayOutputStream();
           9int ch = 0;
          10while ((ch = fis.read()) != -1)
          11{
          12baos.write(ch);
          13
          14}

          15data = baos.toByteArray();
          16}
           catch (IOException e)
          17{
          18e.printStackTrace();
          19}

          20
          21return data;
          22}

          23


          這里我們是從D盤裝載一個類。

          下面我們提供一個類public class MyApp{},類中沒有定義任何方法和變量,下面我們編譯MyApp.java得到MyApp.class,然后把文件放在D盤的根目錄。為了證明MyApp.class是被我們定義的classloader裝載的,我們在FileClassLoadermain()方法中打印出裝載MyApp.class的類裝載器的名稱。

           1public static void main(String[] args) throws Exception
           2{
           3FileClassLoader loader = new FileClassLoader();
           4Class objClass = loader.loadClass("MyApp"true);
           5Object obj = objClass.newInstance();
           6System.out.println(objClass.getName());
           7System.out.println(objClass.getClassLoader());
           8
           9
          10}

          11


          編譯FileClassLoader
          javac FileClassLoader.java
          然后運行java FileClassLoader 可以看到輸出結果為

          MyApp
          FileClassLoader@1a5ab41

          如果你把MyApp.class放入到你程序的所在目錄會出現什么情況呢?讀者自己實踐一下吧!

          結果為:MyApp

          sun.misc.Launcher$AppClassLoader@92e78c

          下面給出FileClassLoader的源代碼。/*

            1* Created on 2005-7-27
            2
            3*
            4
            5* To change the template for this generated file go to
            6
            7* Window>Preferences>Java>Code Generation>Code and Comments
            8
            9*/
           10
           11
           12/**
           13
           14@author liuxiang
           15
           16*
           17
           18* To change the template for this generated type comment go to
           19
           20* Window>Preferences>Java>Code Generation>Code and Comments
           21
           22*/

           23
           24import java.io.ByteArrayOutputStream;
           25
           26import java.io.File;
           27
           28import java.io.FileInputStream;
           29
           30import java.io.IOException;
           31
           32public class FileClassLoader extends ClassLoader
           33
           34{
           35
           36public static final String drive = "d:/";
           37
           38public static final String fileType = ".class";
           39
           40
           41public FileClassLoader() {
           42
           43super();
           44
           45
           46}

           47
           48
           49public FileClassLoader(ClassLoader arg0) {
           50
           51super(arg0);
           52
           53}

           54
           55
           56public Class findClass(String name)
           57
           58{
           59
           60byte[] data = loadClassData(name);
           61
           62/*
           63
           64* Converts an array of bytes into an instance of class Class. 
           65
           66* Before the Class can be used it must be resolved. 
           67
           68
           69
           70* This method assigns a default ProtectionDomain to the newly 
           71
           72* defined class. The ProtectionDomain contains the set of 
           73
           74* permissions granted when a call to Policy.getPolicy().getPermissions() 
           75
           76* is made with a code source of null,null. The default domain 
           77
           78* is created on the first invocation of defineClass, and re-used 
           79
           80* on subsequent calls. 
           81
           82* To assign a specific ProtectionDomain to the class, use the 
           83
           84* defineClass method that takes a ProtectionDomain as one of 
           85
           86* its arguments. 
           87
           88*/

           89
           90/*
           91
           92* 該方法接受由原始字節組成的數組并把它轉化成class對象
           93
           94* 原始字節包含從文件系統或網絡裝入的data
           95
           96* defineClass管理JVM中許多復雜、神秘和依賴于實現的方面————
           97
           98* ————它把字節碼分析成運行時數據結構、校驗有效性等。
           99
          100*/

          101
          102return defineClass(name, data, 0, data.length);
          103
          104}

          105
          106
          107/*
          108
          109* 將對應的Class文件讀為byte[]
          110
          111*/

          112
          113public byte[] loadClassData(String name)
          114
          115{
          116
          117FileInputStream fis = null;
          118
          119byte[] data = null;
          120
          121try
          122
          123{
          124
          125//裝載d:根目錄下面的.class文件到data中
          126
          127fis = new FileInputStream(new File(drive + name + fileType));
          128
          129ByteArrayOutputStream baos = new ByteArrayOutputStream();
          130
          131int ch = 0;
          132
          133while ((ch = fis.read()) != -1)
          134
          135{
          136
          137baos.write(ch);
          138
          139
          140}

          141
          142data = baos.toByteArray();
          143
          144}
           catch (IOException e)
          145
          146{
          147
          148e.printStackTrace();
          149
          150}

          151
          152
          153return data;
          154
          155}
           
          156
          157
          158public static void main(String[] args) throws Exception
          159
          160{
          161
          162FileClassLoader loader = new FileClassLoader();
          163
          164//裝載類MyApp
          165
          166Class objClass = loader.loadClass("MyApp"true);
          167
          168//生成MyApp的一個實例
          169
          170Object obj = objClass.newInstance();
          171
          172//獲得類的名稱
          173
          174System.out.println(objClass.getName());
          175
          176//獲得類的裝載器的名稱
          177
          178System.out.println(objClass.getClassLoader()); 
          179
          180}

          181
          182}

          183
          posted on 2007-06-26 14:27 冰封的愛 閱讀(265) 評論(0)  編輯  收藏 所屬分類: 技術
          <2025年7月>
          293012345
          6789101112
          13141516171819
          20212223242526
          272829303112
          3456789

          常用鏈接

          留言簿(3)

          隨筆檔案

          文章分類

          文章檔案

          相冊

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 贺州市| 元氏县| 荣昌县| 呼图壁县| 教育| 曲靖市| 阿图什市| 集安市| 瓦房店市| 泰宁县| 延吉市| 化州市| 洞口县| 克东县| 昌黎县| 清镇市| 马山县| 鄂伦春自治旗| 新巴尔虎右旗| 丰台区| 桂平市| 隆尧县| 韶关市| 额敏县| 新邵县| 泽州县| 内黄县| 金阳县| 吴江市| 马山县| 六枝特区| 大同市| 桑植县| 自治县| 文山县| 军事| 昌江| 东乡族自治县| 林口县| 固阳县| 务川|