1. 程式人生 > >淺析ClassLoader的雙親委派

淺析ClassLoader的雙親委派

小引

public class Demo {
    public static void main(String[] args) {
        System.out.println(Demo.class.getClassLoader().toString());
    }
}

輸出

sun.misc.Launcher$AppClassLoader@18b4aac2

小n:都說java中的類載入器是雙親委派原則,為啥載入我這個類的是AppClassLoader呢?不應該是類載入器的大佬BootStrapClassLoader嗎?
大N:看來你還沒有完全理解雙親委派原則呀,今天我們就來談一談!

正文

我們平常敲的程式碼xx.java都是原始檔,給程式設計師看的,機器可是看不懂的。於是我們需要先將java原始檔編譯成為xx.class檔案,然後將這個class檔案交給Java虛擬機器。虛擬機器再將這些class檔案根據不同的平臺轉換成為不同的機器碼在不同的機器上進行執行,這也就是Java所謂的跨平臺。今天我們主要說這個步驟——將class檔案交給虛擬機器。
原來總會這樣說:類載入就是雙親委派機制,當類載入器收到類載入的請求的時候自己不會去載入,而是交給父類載入器進行載入。
這句話不能說錯誤,但確實不怎麼嚴謹。讓人首先感覺所有類都是頂層類載入器進行載入的,就像文章開頭小n的問題,他認為雙親委派就是把載入任務都給了bootStrap類載入器。

我們看一下類載入器實際到底是如何進行載入的

// First, check if the class has already been loaded,首先檢查這個類是否已經載入(最終的檢查方法是個本地方法)
            Class<?> c = findLoadedClass(name);
            if (c == null) {//如果這個類還沒有被載入
                long t0 = System.nanoTime();
                try {
                    if (parent != null)
{//有父載入器就交給父載入器去載入 c = parent.loadClass(name, false); } else {//父載入器為空則呼叫BootstrapClassLoader c = findBootstrapClassOrNull(name); } } catch (ClassNotFoundException e) { // ClassNotFoundException thrown if class not found // from the non-null parent class loader } if (c == null) { // If still not found, then invoke findClass in order // to find the class. long t1 = System.nanoTime(); //在指定的路徑下去尋找需要載入的class檔案 c = findClass(name); // this is the defining class loader; record the stats sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0); sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1); sun.misc.PerfCounter.getFindClasses().increment(); } } if (resolve) { resolveClass(c); } return c;

1、檢視這個類是否已經被載入,如果是,返回這個類;如果沒有,交給父類載入器。
2、如果父類載入器為null,那麼傳給bootstrap類載入器。
*前兩步就是我們對雙親委派的一個感性認識,感覺最終傳到bootstrap之後,bootstrap直接載入就完事了,其實不然
3、bootstrap首先檢視這個class檔案是否已經載入,如果還沒有載入,就去指定路徑中尋找這個class檔案,這個查詢的過程就是以上程式碼中對應的findClass()方法。如果找不到,返回null。注意這個指定路徑,對與bootstarp類載入器來說這個路徑就是JDK\jre\lib,對與ExtClassloader這個指定路徑就是JDK\jre\lib\ext。bootstrap在這個路徑下找不到我們這個Demo的class檔案,於是就直接返回null。
4、bootstrap返回之後,extClassLoader進行一樣的尋找,也沒找到,於是再次返回,就到了AppClassLoader中。AppClassLoader在的對應路徑是classpath,在這個路徑下找到了Demo.class,並將它載入進虛擬機器。

總結和附加幾個知識點

  • 父類載入器和子類載入器不是繼承的關係,而是組合。子類載入器中有一個欄位指向父類載入器。注意讀法(父 (停頓) 類載入器)
  • 雙親委派是為了避免重複載入同一個類,保證類的唯一性
  • 雙親委派有一個向上傳遞的過程和向下查詢的過程

相關推薦

java classloader雙親委派原則

1.1  class loader 1.1.1    載入器型別 1.1.1.1  bootstrap class loader 引導類載入器/啟動類載入器,用來載入java的核心庫。主要是 jre/lib目錄(來源於環境變數sun.boot.class

違反ClassLoader雙親委派機制三部曲第二部——Tomcat類載入機制

前言: 本文是基於 ClassLoader雙親委派機制原始碼分析 瞭解過正統JDK類載入機制及其實現原理的基礎上,進而分析這種思想如何應用到Tomcat這個web容器中,從原始碼的角度對 違反ClassLoader雙親委派機制三部曲之首部——JDBC驅動載入 中提出的To

一次嘗試繞過ClassLoader雙親委派的實驗

一、文章來由 來阿里玩Java也有一個多月了,一直對Java虛擬機器比較感興趣,而ClassLoader是整個class載入過程中很重要的元件。而classloader有個雙親委派模型,師兄說這個模型不能破壞,於是打賭一試。 相信如果問:為什麼要雙親委派

Java 類載入器(ClassLoader)/雙親委派模型

ClassLoader類載入器 Class類描述的是整個類的資訊,在Class類中提供的forName()方法,這個方法根據ClassPath配置的路徑進行類的載入,如果說現在你的類的載入路徑可能是網路、檔案,這個時候就必須實現類載入器,也就是ClassLoa

淺析ClassLoader雙親委派

小引 public class Demo { public static void main(String[] args) { System.out.println(Demo.class.getClassLoader().toString

ClassLoader雙親委派機制

博文主要講classloader的模型、作用和使用,內容是作者學習java反射機制有關知識時記錄的筆記。 ClassLoader ClassLoad:類載入器(class loader)用來載入 Java 類到 Java 虛擬機器中。Java 源程式(.

淺談JVM(一) ClassLoader雙親委派和沙箱機制

JVM(Java Virtual Machine)   java虛擬機器  JVM執行在作業系統之上,與計算機硬體沒有互動 JVM整體執行流程需要用到的資源 可以說分以下標紅的5部分組成 class files 被java命令執行 將類資訊通過類裝載器(ClassLoade

ClassLoader學習之 自定義classLoader雙親委派原理

ClassLoader學習之  自定義classLoader和雙親委派原理1、ClassLoader原理介紹​ ClassLoader使用的是雙親委託模型來搜尋類的,每個ClassLoad

ClassLoader&雙親委派&類初始化過程

1.class sycle   類載入的生命週期:載入(Loading)–>驗證(Verification)–>準備(Preparation)–>解析(Resolution)–>初始化(Initialization)–>使用(Using)–>解除安裝(Unloading)。

類加載器和雙親委派

層次 方法 類的加載 實例 ima isa sass 自己 sas    這張圖清晰吧 類加載器的作用不僅僅是實現類的加載,它還與類的的“相等”判定有關,關系著Java“相等”判定方法的返回結果,只有在滿足如下三個類“相等”判定條件,才能判定兩個類相等。 1、兩個類來自同一

關於Java類加載雙親委派機制的思考(附一道面試題)

另類 app 類庫 .com 任務 發現 clas context 表示 預定義類加載器和雙親委派機制 JVM預定義的三種類型類加載器: 啟動(Bootstrap)類加載器:是用本地代碼實現的類裝入器,它負責將 <Java_Runtime_Home>/l

Java 雙親委派模型

雙親委派模型 mode 分享圖片 雙親委派 es2017 加載 png log blog 1. Java 類加載器的分類 2. 雙親委派模型 Parents Delegration Model Java 雙親委派模型

類加載器-雙親委派模型

獨立 我們 java_home ots log 上下文 組合 obj c++ 雙親委派模型從虛擬機的角度來講,只存在兩種類加載器: (1)啟動類加載器:Bootstrap ClassLoader,由C++實現,不是ClassLoader子類,屬於虛擬機自身的一部分 (2)所

Java雙親委派模型

static AS eight 這樣的 found 類加載器 can 兩種 RR Java雙親委派模型詳解 我們在了解雙親委派模型之前,不得不先了解一下什麽是類加載器。虛擬機設計團隊之初是希望類加載過程“通過一個類的全限定名來獲取描述該類的二進制字節流”這

java的類加載器體系結構和雙親委派機制

答案 類加載器 父類 編譯 自己 體系 文件加載 ext 類名 類加載器將字節碼文件加載到內存中,同時在方法區中生成對應的java.land.class對象 作為外部訪問方法區的入口。 類加載器的層次結構:            引導類加載器《-------------擴

JVM理論:(三/6)類加載器、雙親委派

rap 自定義 pan 類名 唯一性 sso 返回 工作過程 lse 一、類與類加載器   允許類加載階段中的“通過一個類的全限定名來獲取描述此類的二進制字節流”這個動作可以讓應用程序自己決定如何去獲取所需要的類。實現這個動作的代碼模塊稱為“類加載器”。   類加載器雖然只

雙親委派模型

都是 載器 多個 完成 自己 分享圖片 http 就會 src 本文參考《深入理解java虛擬機》 雙親委派模型中將 類加載器進行等級劃分,當一個類加載器收到一個類加載的請求時,自己先不會處理這個請求,而是將這個請求交給父類加載器,最終請求會傳到啟動類加載器,如果父類加載

JVM總括四-類載入過程、雙親委派模型、物件例項化

JVM總括四-類載入過程、雙親委派模型、物件例項化 一、 類載入過程 一定要注意每個過程執行的內容!!!!!! 1、Load:   將編譯後的.class檔案以二進位制流的方式載入到JVM記憶體中,並轉化為特定的資料結構,用到的就是classLoad二類載入器。這個過程中校驗cafe babe

JVM總括四-類加載過程、雙親委派模型、對象實例化

jvm 地址 解析 img 指向 image pan 編譯 jvm內存 JVM總括四-類加載過程、雙親委派模型、對象實例化 一、 類加載過程 一定要註意每個過程執行的內容!!!!!! 1、Load:   將編譯後的.class文件以二進制流的方式加載到JVM內存中,並轉

JVM總括四-類載入過程、雙親委派模型、物件例項化過程 JVM思考-init和clinit區別

JVM總括四-類載入過程、雙親委派模型、物件例項化過程 目錄:JVM總括:目錄 一、 類載入過程 類載入過程就是將.class檔案轉化為Class物件,類例項化的過程,(User user = new User(); 這個過程是物件例項化的過程); 一個.class檔案只有一個Class物件(位元