淺析Java雙親委派機制及其作用

来源:https://www.cnblogs.com/RebeccaYuan/archive/2022/06/07/16350750.html
-Advertisement-
Play Games

雙親委派機制:當某個類載入器準備載入一個.class位元組碼文件時,它首先將這個載入任務委派給上一級類載入器,上一級載入器再委派到更上一級類載入器,遞歸這個操作直到最頂級的類載入器。 一、類載入器的類別 在介紹Java的雙親委派機制的時候,不得不提ClassLoader(類載入器) 我們編譯的Java ...


雙親委派機制:當某個類載入器準備載入一個.class位元組碼文件時,它首先將這個載入任務委派給上一級類載入器,上一級載入器再委派到更上一級類載入器,遞歸這個操作直到最頂級的類載入器。

一、類載入器的類別

在介紹Java的雙親委派機制的時候,不得不提ClassLoader(類載入器)

我們編譯的Java代碼是如何在JVM中運行的?首先源程式(.java文件)被Java編譯器編譯為.class位元組碼文件,然後ClassLoader負責將這些class文件載入到JVM中去執行。

如上圖所示:JVM提供了三層類載入器

  1. BootStrapClassLoader(引導類載入器)

    引導類載入器:用C++編寫,是Java自帶的類載入器,用於載入JDK內部的類;主要負責載入核心的類庫,構造ExtensionClassLoaderAppClassLoader。Bootstrap類載入器用於載入JDK中$JAVA_HOME/jre/lib下麵的那些類,比如rt.jar包裡面的類。

    由於引導類載入器涉及到虛擬機本地實現細節,開發者無法直接獲取到引導類載入器的引用,所以不允許直接通過引用進行操作。

  2. ExtensionClassLoader(擴展類載入器)

    擴展類載入器:主要負責載入 jre/lib/ext 目錄下的一些擴展的jar包或-Djava.ext.dirs指定目錄下的jar包。主要用於載入JDK擴展包里的類。一般$JAVA_HOME/lib/ext下麵的包都是通過這個類載入器載入的

    Java編寫,載入擴展庫,如classpath中的jrejavax.*或者java.ext.dir 指定位置中的類,開發者可以直接使用標準擴展類載入器。

  3. AppClassLoader(系統類載入器)

    系統類載入器:負責java -classpath或-Djava.class.path所指定目錄下的類與jar包

    主要負責載入應用程式的主函數類。用來載入開發人員自己平時寫的應用代碼的類的,載入存放在classpath路徑下的那些應用程式級別的類的。

    Java編寫,載入程式所在的目錄

  4. CustomClassLoader(用戶自定義類載入器)

     java編寫,用戶自定義的類載入器,可載入指定路徑的class文件

二、工作原理

  • 如果一個類載入器收到類載入的請求,並不會自己先載入,而是將載入請求委托給父類的載入器進行載入;
  • 如果父類的載入器還存在其父類載入器,則進一步向上委托,遞歸這個操作,直至到達最高級的引導類載入器;
  • 如果父類載入器可以完成載入請求,則成功返回,如果父類載入器不能完成載入請求,則子載入器才會嘗試自己去載入,這就是雙親委派機制;
  • 父類載入器一層層向下分派任務,如果子類載入器能載入則載入此類,如果直到系統類載入器也無法載入,則拋出異常。

從上圖我們就容易理解,當一個Test.class文件要載入時:

  • 不考慮用戶自定義的類載入器,首先會在AppClassLoader檢查是否載入過,如果已經載入過就無需在載入了;如果沒有,就會委派到父載入器,然後調用父載入器的loadClass方法

  • 父類載入器同理也會先檢查是否載入過,如果沒有再向上委派

    這個類似遞歸的過程,直到到達BootstrapClassLoader之前,都只是檢查是否載入過,並不會選擇自己載入

  • 直到BootstrapClassLoader,已經沒有父載入器了,這是開始考慮自己是否能載入了,如果自己不能載入,則下沉到子類載入器去載入,直到最底層

  • 如果沒有任何類載入器能夠載入,則拋出ClassNotFoundException異常

三、雙親委派機制的作用

  • 防止同一個.class文件被重覆載入。通過委派機制向上問一問,如果已經載入過,就不用再載入一次,保證數據安全
  • 保證核心.class文件不能被篡改。通過委派機制,即使不小心篡改了核心.class文件,也不會被執行,保證了系統級別的類的安全性

四、代碼淺析

舉例1:建立一個java.lang.String類,寫上static代碼塊

在另外的程式中載入 String 類,看看載入的 String 類是 JDK 自帶的 String 類,還是我們自己編寫的 String 類

從輸出結果可以看到,程式並沒有輸出靜態代碼塊的內容,自定義String類並沒有被載入,所以載入的是JDK內置的String類

這是因為我們自定義的String類本應被AppClassLoader載入,但AppClassLoader並不會先自己載入,而是把載入請求委托給父類的載入器去執行,到了ExtensionClassLoader發現String類不歸自己管,於是委托給父類的載入器(BootStrapClassLoader),引導類載入器發現是java.lang包,所以載入的就是JDK內置的String類

舉例2:在自定義的String類中寫個main()方法

由於雙親委派機制載入的是JDK內置的String類,而在引導類載入器中的核心類庫API里的String類並沒有main()方法

舉例3:在java.lang包下自定義一個AbcTest類

報錯,java.lang包下不允許自定義類


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • """python的拆包和封包之 *號在函數形參和實參的區別1. 在函數形參定義時添加*就是封包過程,封包預設是以元組形式進行封包2. 在函數實參調用過程添加*就是拆包過程,拆包過程中會報列表或者元組拆成單個元素"""subject = ["math", "chinese", 'english', ...
  • 剛剛看到一篇博客,說 stdbind 無法綁定正確的重載函數。這裡的問題並不是 stdbind 能力不足,而是將函數名傳遞給 std::bind 時編譯器無法取到這個函數的地址(也就是符號,編譯器會先解析成符號,鏈接器再替換為地址),因為有多個重載函數都是這個名字。核心問題是無法通過函數名取到想要的 ...
  • Spring Ioc源碼分析系列--自動註入迴圈依賴的處理 前言 前面的文章Spring Ioc源碼分析系列--Bean實例化過程(二)在講解到Spring創建bean出現迴圈依賴的時候並沒有深入去分析了,而是留到了這一篇去分析。為什麼要另起一篇,首先迴圈依賴是個很經典的問題,也是面試屢屢被問到的問 ...
  • 作者:lex-wu 來源:www.cnblogs.com/lex-wu/p/14610110.html 前言 最初是覺得我們打工人,在歷史的浪潮中,我們都被推著上岸。電子產品和移動互聯網,把我們的生活節奏大大提速了,所以很多人都忘記了生活和工作中的關係。 所以在深圳這個城市的各個街道上,都能看到忙忙 ...
  • 整型是我們日常生活中最常用到的基礎數據類型,看這篇文章之前,我想問: 我們真的像自己認為的那麼理解 Java 內的整型嗎? 也許看完本篇文章你就有自己的答案。 C 語言 提供瞭如下的整型 學習 Java 的整型之前,讓我們看看它的前輩——C 語言的實現。 讓我們更好地瞭解它的設計。 數據類型 占用字 ...
  • 成交量(volume)是投資中一個非常重要的變數,它是指在某一時段內具體的交易數,可以在分時圖中繪製,包括日線圖、周線圖、月線圖甚至是5分鐘、30分鐘、60分鐘圖中繪製。 股票市場成交量的變化反映了資金進出市場的情況,成交量是判斷市場走勢的重要指標。一般情況下,成交量大且價格上漲的股票,趨勢向好。成 ...
  • 有時候,我們將數據變換之後再繪圖,一方面,可以突出某些區域的數據;另一方面,變換之後可以更好的看出數據之間的關係。 matplotlib 提供了兩種變換數據的方式,一種是 Scale(縮放),一種是Projection(投影)。 Scale是對數據的一個維度進行變換,Projection則是對2個或 ...
  • 1、synchronized關鍵字簡介 synchronized是java中的一個關鍵字,在中文中為同步,也被稱之為'同步鎖',以此來達到多線程併發訪問時候的併發安全問題,可以用來修飾代碼塊、非靜態方法。靜態方法等; 修飾代碼塊時:給當前指定的對象加鎖 修飾非靜態方法時:作用於當前實例加鎖 修飾靜態 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...