<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    JimmyJin
    走在架構(gòu)師的大道上,學(xué)習(xí)的樂趣就在于將知識應(yīng)用于具體實踐中,在實戰(zhàn)中實現(xiàn)知識的價值。
    posts - 4,comments - 0,trackbacks - 0

    類加載器基本概念

    顧名思義,類加載器(class loader)用來加載 Java 類到 Java 虛擬機(jī)中。一般來說,Java 虛擬機(jī)使用 Java 類的方式如下:Java 源程序(.java 文件)在經(jīng)過 Java 編譯器編譯之后就被轉(zhuǎn)換成 Java 字節(jié)代碼(.class 文件)。類加載器負(fù)責(zé)讀取 Java 字節(jié)代碼,并轉(zhuǎn)換成 java.lang.Class類的一個實例。每個這樣的實例用來表示一個 Java 類。通過此實例的 newInstance()方法就可以創(chuàng)建出該類的一個對象。實際的情況可能更加復(fù)雜,比如 Java 字節(jié)代碼可能是通過工具動態(tài)生成的,也可能是通過網(wǎng)絡(luò)下載的。
    基本上所有的類加載器都是 java.lang.ClassLoader類的一個實例。

    public abstract class ClassLoader
    extends Object

    類加載器的樹狀組織結(jié)構(gòu)

    Java 中的類加載器大致可以分成兩類,一類是系統(tǒng)提供的,另外一類則是由 Java 應(yīng)用開發(fā)人員編寫的。系統(tǒng)提供的類加載器主要有下面三個:

    • 引導(dǎo)類加載器(bootstrap class loader):它用來加載 Java 的核心庫,是用原生代碼來實現(xiàn)的,并不繼承自java.lang.ClassLoader。其父類加載器為NULL。
    • 擴(kuò)展類加載器(extensions class loader):它用來加載 Java 的擴(kuò)展庫。Java 虛擬機(jī)的實現(xiàn)會提供一個擴(kuò)展庫目錄。該類加載器在此目錄里面查找并加載 Java 類。
    • 系統(tǒng)類加載器(system class loader):它根據(jù) Java 應(yīng)用的類路徑(CLASSPATH)來加載 Java 類。一般來說,Java 應(yīng)用的類都是由它來完成加載的。可以通過 ClassLoader.getSystemClassLoader()來獲取它。

    除了系統(tǒng)提供的類加載器以外,開發(fā)人員可以通過繼承 java.lang.ClassLoader類的方式實現(xiàn)自己的類加載器,以滿足一些特殊的需求。

    除了引導(dǎo)類加載器之外,所有的類加器都有一個父類加載器。通過ClassLoader中給出的 getParent()方法可以得到。對于系統(tǒng)提供的類加載器來說,系統(tǒng)類加載器的父類加載器是擴(kuò)展類加載器,而擴(kuò)展類加載器的父類加載器是引導(dǎo)類加載器;對于開發(fā)人員編寫的類加載器來說,其父類加載器是加載此類加載器 Java 類的類加載器。因為類加載器 Java 類如同其它的 Java 類一樣,也是要由類加載器來加載的。一般來說,開發(fā)人員編寫的類加載器的父類加載器是系統(tǒng)類加載器。類加載器通過這種方式組織起來,形成樹狀結(jié)構(gòu)。樹的根節(jié)點(diǎn)就是引導(dǎo)類加載器。圖 1中給出了一個典型的類加載器樹狀組織結(jié)構(gòu)示意圖,其中的箭頭指向的是父類加載器。


    圖 1. 類加載器樹狀組織結(jié)構(gòu)示意圖
    類加載器樹狀組織結(jié)構(gòu)示意圖
    類是由它的全名和類加載器來確定的,由此我們可以看到一個有趣的現(xiàn)象即
    在同一個虛擬機(jī)中,可以有兩個類,它們的類名和包名都是相同的。這項技術(shù)在加載來自多處的代碼時非常有用如熱布署就是應(yīng)用這一特性來實現(xiàn)的。
    JVM啟動時,首先加載類加載器及其相對應(yīng)的字節(jié)碼(class),其順序為: 
    先是bootstrap classloader------(rt.jar,然后是extension classloader ------(jre/lib/ext) ,最后才是system classloader ------(CLASSPATH 大家會發(fā)現(xiàn)加載的Class越是重要的越在靠前面。這樣做的原因是出于安全性的考慮,試想如果system classloader“親自”加載了一個具有破壞性的“java.lang.System”類的后果吧。這種委托機(jī)制保證了用戶即使具有一個這樣的類,也把它加入到了類路徑中,但是它永遠(yuǎn)不會被載入,因為這個類總是由bootstrap classloader來加載的。大家可以執(zhí)行一下以下的代碼: 
        System.out.println(System.class.getClassLoader()); 
    將會看到結(jié)果是null,這就表明java.lang.System是由bootstrap classloader加載的,因為bootstrap classloader(用C++實現(xiàn)的)不是一個真正的ClassLoader實例,而是由JVM實現(xiàn)的。
    類的加載過程:
    我們知道每個類都有它自已的類加載器(Class.getClassLoader),
    除了引導(dǎo)類加載器之外,所有的類加器都有一個父類加載器。通過ClassLoader中給出的 getParent()方法可以得到。對于系統(tǒng)提供的類加載器來說,系統(tǒng)類加載器的父類加載器是擴(kuò)展類加載器,而擴(kuò)展類加載器的父類加載器是引導(dǎo)類加載器;對于開發(fā)人員編寫的類加載器來說,其父類加載器是加載此類加載器 Java 類的類加載器。

     

    編寫你自已的類加載器:
    只需要繼承ClassLoader類,然后重寫其findClass(String classname)即可。
    ClassLoader超類的loadClass方法用于將類的加載操作委托給其父類加載器去進(jìn)行,
    只有當(dāng)類尚未加載并且其所有父類加載器也沒有加載此類時,才能調(diào)用你自已的類加載器中的findclass方法。
    例法:
    class CryptoClassLoader extends ClassLoader
    {
       /**
        * Constructs a crypto class loader.
        * @param k the decryption key
        */
       public CryptoClassLoader(int k)
       {
          key = k;
       }
       protected Class findClass(String name
       {
          byte[] classBytes = null;
             try {
    classBytes = loadClassBytes(name);
    } catch (IOException e) {
    e.printStackTrace();
    }
         //defineClass 方法將一個 byte 數(shù)組轉(zhuǎn)換為 Class 類的實例。
          Class cl = defineClass(name, classBytes, 0, classBytes.length);
          if (cl == null)
    try {
    throw new ClassNotFoundException(name);
    } catch (ClassNotFoundException e) {
    e.printStackTrace();
    }
          return cl;
       }
       /**
        * Loads and decrypt the class file bytes.
        * @param name the class name
        * @return an array with the class file bytes
        */
       private byte[] loadClassBytes(String name) throws IOException
       {
     // String cname="classes/com/jimmy/corejava/classloaderTest"+"/"+name+".class";
         String cname="classes/com/jimmy/corejava/classloaderTest"+"/"+name+".class";
     
          FileInputStream in = null;
          in = new FileInputStream(cname);
          try
          {
             ByteArrayOutputStream buffer = new ByteArrayOutputStream();
             int ch;
             while ((ch = in.read()) != -1)
             {
            buffer.write(ch);
             }
             in.close();
             return buffer.toByteArray();
          }
          finally
          {
             in.close();
          }
       }
       private int key;
    }
    為方便測試時,我們可事先給無法找到類的路徑,以防止其其父類加載器加載其類,這們強(qiáng)迫它調(diào)用我們的類加載器,然后在我們的findclass、loadClassBytes 方法中給出能找到此類的路徑,這樣就能得到我們的目的了。
    public class ClassLoaderTest
    {
       public static void main(String[] args)
       {
         
    //   String firstClass="v2ch09.ClassLoaderTest.Calculator";
      String firstClass="FirstClass";
      try {
            ClassLoader loader = new CryptoClassLoader(Integer.parseInt("3"));
    System.out.println("=====>"+ClassLoaderTest.class.getClassLoader().toString());
    Object fl= loader.loadClass(firstClass).newInstance();
    System.out.println("=====>"+fl.getClass().getClassLoader().toString());
    System.out.println(System.class.getClassLoader()); 
    } catch (ClassNotFoundException e) {
    e.printStackTrace();
    } catch (InstantiationException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    } catch (IllegalAccessException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
       }
    }
    打印結(jié)果為:
    =====>sun.misc.Launcher$AppClassLoader@addbf1
    =====>v2ch09.ClassLoaderTest.CryptoClassLoader@61de33
    運(yùn)用自定義的類加載器,我們可以實現(xiàn)代碼的加密、解密等。
    posted on 2012-05-30 22:35 jimmy2009 閱讀(371) 評論(0)  編輯  收藏

    只有注冊用戶登錄后才能發(fā)表評論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 亚洲人成在久久综合网站| 免费一级毛片在播放视频| 亚洲国产成人一区二区精品区| 青草青草视频2免费观看| 免费女人18毛片a级毛片视频| 亚洲男人的天堂网站| 国产成人免费a在线资源| 爱情岛论坛亚洲品质自拍视频网站 | 免费看香港一级毛片| 亚洲av无码无线在线观看| 国产男女猛烈无遮挡免费视频网站 | 免费观看91视频| 久久久久亚洲精品日久生情| 亚洲免费在线观看视频| 亚洲性无码AV中文字幕| 国产精品免费视频播放器| 免费无毒a网站在线观看| 国产V亚洲V天堂A无码| 8888四色奇米在线观看免费看| 亚洲精品在线播放| 精品免费久久久久久成人影院| 精品视频免费在线| 国产亚洲综合一区柠檬导航| 免费国产黄网站在线观看可以下载| 亚洲天堂一区二区| 好吊妞在线成人免费| 无码毛片一区二区三区视频免费播放| 亚洲欧洲无码AV电影在线观看| 久久这里只精品国产免费10| 国产精品亚洲片夜色在线| 亚洲Av无码国产情品久久| 黄色免费在线网站| 91丁香亚洲综合社区| 亚洲黄片毛片在线观看| 日本xxxx色视频在线观看免费| 亚洲av乱码一区二区三区| 亚洲人成无码网站久久99热国产| 99ee6热久久免费精品6| 免费无码AV一区二区| 亚洲无砖砖区免费| 国产精品亚洲mnbav网站 |