JVM-------類加載器種類和雙親委派機制

類加載器

首先應該明確jvm有公開的標準,並且有很多實現版本,最爲常用的就是HotSpot版(這個版本的jvm是由c++語言進行實現)。
jvm版本查看
其次jvm的作用:JVM中類加載器的作用就是:加載class字節碼文件,加載並初始化Class。
過程如圖所示:(簡略圖)
在這裏插入圖片描述
java中類加載器有4種:由高到低的排序
1.虛擬機自帶的加載器
2.啓動類(根)加載器 (位於jdk的lib中的 rt.jar)
3.擴展類加載器(位於jre/lib/ext目錄下)
4.應用程序(系統類)加載器
它們的執行順序是4321,由高到低(1234)是父子類關係。
當明確過這些概念後就可以瞭解雙親委派機制。

public class Student {
    public static void main(String[] args) {
        Student s1 = new Student();
        Class<? extends Student> aClass1 = s1.getClass();
        ClassLoader classLoader = aClass1.getClassLoader();
        System.out.println(classLoader);  
        //輸出結果AppClassLoader
        System.out.println(classLoader.getParent()); 
        //輸出結果ExtClassLoader  擴展類加載器   jre/lib/ext
        System.out.println(classLoader.getParent().getParent());  
        //輸出結果 null  可能造成的原因1.不存在  2.java程序獲取不到  rt.jar
        //而null是因爲 jvm是由c++寫的,能夠獲取到,但是無法調用
    }
}

雙親委派機制

1.當類加載器需要加載初始類(即收到加載類的請求時),並不會立即執行,而是調用父類的類加載器去執行,當父類類加載器還存在父類時,則再由父類的上層類加載器執行,最終到達啓動類加載器進行執行。AppClassLoader—>ExtClassLoader—>Bootstrap ClassLoder
2.如果在啓動類加載器執行時,能夠加載到該類,則由啓動器加載類進行加載。
3.如果父類加載器無法加載這個類,就拋出異常,調用子類加載器,進行加載,依次往下執行,直到某各類加載器能夠完成加載。Bootstrap ClassLoder—>ExtClassLoader—>AppClassLoader
簡單地說就是:子類給父類,父類加載器能加載就優先加載,不能則父類再給子類類加載器。

這種機制首先能夠避免重複加載,其次能夠保護java的核心api不被破壞。
舉個例子:
大家有沒有想過寫一個和SreingAPI同名的類,即創建java.lang.String類,同時定義一個toString方法,那麼在String類中的main方法執行入口中去執行這個String 對象的toString方法,結果會如何呢?

package java.lang;   //創建和系統StringAPI,同類名的String類
public class String {

    public String toString(){
        return "hello";
    }

    public static void main(String[] args) {
        String s = new String();
        System.out.println(s);
    }
}`.

結果當然會報錯:錯誤信息如圖所示
在這裏插入圖片描述
原因就是:類加載器一層一層向上找,最終使用啓動類加載器,而啓動類加載器位於jdk的rt.jar,在這裏加載到的類時java的核心api:String.那麼就不會執行自己定義的String類,而在覈心API中並沒有main方法,因此保存會找不到。

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