Java虛擬機-類加載器

1.類加載器

  • 虛擬機的設計團隊把類加載階段中的“通過一個類的全限定名來獲取描述此類的二進制流”這個動作放到Java虛擬機外部去實現,以便讓應用程序自己決定如何去獲取所需要的類。實現這個動作的代碼模塊稱之爲類加載器。
  • 只有被同一個類加載器加載的類纔可能會相等。相同的字節碼被不同的類加載器加載的類不相等。

2.類加載器分類

  •     啓動類加載器

           由C++實現,是虛擬機的一部分,用於加載javahome下的lib目錄下的類。

  •     擴展類加載器

           加載javahome下/lib/ext目錄中的類。

  •     應用程序類加載器

           加載用戶類路徑上所指定的類庫。 

  •     自定義類加載器

3.自定義類加載器

  •     步驟

        定義一個類,繼承ClassLoader。
        重寫loadClass方法。
        實例化Class對象。

  •     優勢

        類加載器是Java語言的一項創新,也是Java語言流行的重要原因之一,它最新的設計是爲了滿足Java Applet的需求而開發出來的。
        高度的靈活性。
        通過自定義類加載器可以實現熱部署。
        代碼加密。

  • 示例代碼

public class ClassLoaderDemo {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        MyClassLoader myClassLoader = new MyClassLoader();
        Object c = myClassLoader.loadClass("com.my.classloader.ClassLoaderDemo").newInstance();

        System.out.println(c.getClass());
        // c由自定義類加載器加載,而ClassLoaderDemo由應用程序類加載器加載
        // 是兩個不同的類加載器,一個類由兩個不同的了加載器加載,所以兩個類不相等
        System.out.println(c instanceof ClassLoaderDemo);
    }
}

class MyClassLoader extends ClassLoader {
    @Override
    public Class<?> loadClass(String name) throws ClassNotFoundException {
        String fileName = name.substring(name.lastIndexOf(".") + 1) + ".class";
        InputStream inputStream = getClass().getResourceAsStream(fileName);
        if (inputStream == null) {
            return super.loadClass(name);
        }
        try {
            byte[] buffer = new byte[inputStream.available()];
            inputStream.read(buffer);
            return defineClass(name, buffer, 0, buffer.length);
        } catch (Exception e) {
            throw new ClassNotFoundException();
        }
    }
}

4.雙親委派模型
          從JDK1.2開始,java虛擬機規範推薦開發者使用雙親委派模型進行類加載,其加載過程如下:

                                                       
          如果一個類加載器收到了類加載請求,它首先不會自己嘗試加載這個類,而是把類加載請求委派給父類加載器去完成。每一層的類加載器都把類加載請求委派給父類加載器,直到所有的類加載請求都應該傳遞給頂層的啓動類加載器。如果頂層的啓動類加載器無法完成加載請求,子類加載器嘗試去加載,如果連最初發類加載請求的類加載器也無法完成加載請求時,將會拋出ClassNotFoundException,而不再調用其子類加載器去進行類加載。雙親委派模型的類加載機制的優點是java類和它的類加載器一器具備了一種帶優先級的層次關係,越是基礎的類,越是被上層的類加載器進行加載,保證了java程序的穩定運行。

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