類與類加載器

在Java中,類和類加載器是密切相關的兩個概念,理解它們有助于我們更好地掌握Java的運行機制。

什么是Java類?

Java類就像是一個模板或藍圖,它定義了對象的屬性和行為。比如"汽車"可以看作一個類,它有顏色、品牌等屬性,有行駛、剎車等行為。我們根據這個類可以創建具體的汽車對象(如一輛紅色的特斯拉)。

// 汽車類(模板)
class Car {String color;  // 屬性String brand;  // 屬性// 行為void drive() {System.out.println(brand + "汽車正在行駛");}
}// 創建對象(根據模板造具體的車)
Car myCar = new Car();
myCar.color = "紅色";
myCar.brand = "特斯拉";
myCar.drive();  // 輸出:特斯拉汽車正在行駛

什么是類加載器?

類加載器(ClassLoader)就像是"類的搬運工",它的作用是把.class文件(編譯后的類)加載到Java虛擬機(JVM)中,讓JVM能夠認識這個類并使用它。

想象一下:JVM就像一個大型工廠,類就像是生產所需的圖紙。類加載器的工作就是把這些圖紙從文件系統、網絡或其他地方運送到工廠里,供工廠使用。

咱們可以把Java虛擬機(JVM)想象成一個“大工廠”,類加載器就是負責給這個工廠“運圖紙(類)”的工人。

從虛擬機角度看(兩種類加載器)

  • 啟動類加載器(Bootstrap ClassLoader):它是工廠里“最核心的元老級搬運工”,用C++寫的,是虛擬機本身的一部分。專門搬最基礎、最核心的“工廠自帶圖紙”,像java.lang.String這類Java最根本的類,就靠它搬。
  • 其他類加載器:這些是“后來的搬運工”,用Java寫的,和虛擬機是分開的。它們都得繼承java.lang.ClassLoader這個抽象類,負責搬一些額外的圖紙。

從開發者角度看(更細致的劃分)

  • 啟動類加載器:還是那個“核心元老搬運工”,負責搬<JRE_HOME>\lib目錄里(或者-Xbootclasspath參數指定路徑里)、虛擬機能認出來的“核心圖紙”。比如java.util(工具類)、java.io(輸入輸出類)、java.lang(語言基礎類)這些常用基礎類庫。而且它很“傲嬌”,只認文件名,像rt.jar這類符合名字的才搬,名字不對的,哪怕在lib目錄里也不管。另外,Java程序沒法直接調用它。

  • 擴展類加載器(Extension ClassLoader):它是“擴展搬運工”,負責搬<JRE_HOME>/lib/ext目錄或者java.ext.dir系統變量指定路徑里的“擴展圖紙”。像swing(界面相關)、內置js引擎、xml解析器這些以javax開頭的擴展類庫,都由它來搬。開發者是可以直接用這個加載器的。

  • 應用程序類加載器(Application ClassLoader):也叫“系統類加載器”,是“用戶搬運工”。負責搬用戶自己指定的類路徑(ClassPath)里的“圖紙”,比如我們自己寫的類,或者第三方的jar包。如果我們沒自己定義類加載器,程序默認就用它來搬圖紙。而且它可以通過ClassLoadergetSystemClassLoader()方法獲取到,開發者能直接使用。

類與類加載器的關系

  • 每個類被加載到JVM后,都會記錄是被哪個類加載器加載的
  • 類加載器之間存在"父子關系":Application的父是Extension,Extension的父是Bootstrap
  • 判斷兩個類是否相同,不僅要看類名是否一樣,還要看它們是否被同一個類加載器加載

打個比方:兩個名字相同的"汽車"圖紙,如果一個是由"中國搬運工"搬來的,一個是由"美國搬運工"搬來的,JVM會認為它們是不同的類。

為什么需要類加載器?

  1. 實現了類的動態加載:需要用某個類時才加載,不用時不加載,節省資源
  2. 實現了隔離性:不同的類加載器可以加載同名類而不沖突,這對容器(如Tomcat)很重要
  3. 安全性:可以通過自定義類加載器來控制哪些類能被加載,防止惡意代碼

理解類和類加載器的關系,有助于我們解決類沖突、類找不到等問題,也是學習Java反射、動態代理等高級特性的基礎。

在Java類加載機制中,雙親委派模型可以類比成一個公司的文件審批流程,這樣能更通俗易懂地理解。

什么是雙親委派模型

在Java里,類加載器之間存在層次關系,形成了一個類似樹形的結構。除了最頂層的啟動類加載器 ,其他類加載器都有自己的“父加載器”,比如擴展類加載器的父加載器是啟動類加載器,應用程序類加載器的父加載器是擴展類加載器。雙親委派模型規定,當一個類加載器收到類加載請求時,它首先不會自己去嘗試加載這個類,而是把請求委派給父加載器去完成,只有當父加載器無法完成加載任務時,子加載器才會嘗試自己去加載。

用公司審批流程舉例說明

假設你在公司里寫了一份重要的報告,需要經過審批才能正式發布。這就類似于類加載器收到加載類的請求。

  • 部門經理(應用程序類加載器):你作為普通員工,寫好報告后會先交給部門經理,對應應用程序類加載器收到類加載請求,它不會自己先去處理,而是把請求向上提交。
  • 部門總監(擴展類加載器):部門經理拿到你的報告后,不會直接審批,而是交給部門總監,這就好比應用程序類加載器把加載請求交給擴展類加載器。部門總監拿到報告后,同樣也不會直接審批,而是繼續往上提交。
  • 公司老板(啟動類加載器):部門總監把報告交給公司老板,啟動類加載器作為最頂層,先檢查這個報告(類)是不是屬于它負責的核心內容,比如公司的基本規章制度、財務審批流程等相關文件(Java核心類庫) 。如果是,老板就直接審批(加載類);如果不是,比如是關于某個項目的具體報告,老板就會把報告打回給部門總監,說“這事兒不歸我管,你處理一下”。
  • 部門總監處理:部門總監接到老板打回的報告后,查看是否屬于自己職責范圍內,比如一些技術規范、行業標準相關的報告,如果是就審批(加載類);如果不是,再打回給部門經理。
  • 部門經理處理:部門經理接到報告,一看是關于自己部門項目執行情況的報告,就自己審批了(應用程序類加載器自己加載類)。

雙親委派模型的好處

  • 避免重復加載:如果父加載器已經加載過這個類,子加載器就不需要再加載了,節省了資源。就像在公司審批流程中,如果高層已經審批過類似的文件,底層就不用重復審批。
  • 保證安全性:它確保了Java核心類庫的一致性和安全性。因為核心類庫都是由最頂層的啟動類加載器加載的,防止了用戶自定義的類去替換核心類。比如不會出現有人寫一個假的java.lang.String類混入系統,因為啟動類加載器只會加載真正的核心String類 。

對象的創建過程

咱們把Java中對象的創建過程,比作"蓋房子"的過程,這樣就很好理解了:

  1. 確定圖紙(類加載檢查)


1.當你說new 房子()時,JVM首先會檢查"房子"這個類的圖紙(.class文件)有沒有被加載到內存里。如果沒加載,就會讓類加載器去把圖紙搬過來(類加載過程)。
就像蓋房子前,必須先有建筑圖紙,而且圖紙得先拿到工地才行。

  1. 圈地(分配內存)
    圖紙確認后,JVM會在內存里找一塊合適的地方(堆內存),專門用來蓋這個房子(存放對象)。
    相當于開發商在空地上圈出一塊地,大小剛好夠蓋這棟房子。

  1. 地基處理(初始化零值)
    圈好地后,JVM會先把這塊地"打掃干凈",給里面的各種屬性(比如房子的面積、房間數)設置默認值(數字0、布爾false、引用null等)。
    就像蓋房子前,先把地皮整平,打好地基,確保基礎是合格的。

  1. 掛門牌(設置對象頭)
    JVM會給這個對象加一個"身份證"(對象頭),里面記錄著:這個對象屬于哪個類(對應哪個圖紙)、哈希碼、GC信息等。
    相當于給房子掛上門牌,寫明"這是XX小區3號樓",方便后續查找和管理。

  1. 內部裝修(執行初始化)
    最后一步是真正按照圖紙裝修:給屬性賦值(比如面積120平米、3個房間)、執行構造方法里的邏輯(比如安裝門窗、鋪地板)。
    到這一步,房子才算真正蓋好,能住人(使用對象)了。

總結一下:從確認圖紙→分配空間→基礎處理→標記身份→詳細裝修,一步不差,一個對象就創建出來了。就像蓋房子一樣,按流程來才能保證最終的"房子"能用、好用。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/918990.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/918990.shtml
英文地址,請注明出處:http://en.pswp.cn/news/918990.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

一文速通Python并行計算:14 Python異步編程-協程的管理和調度

一文速通 Python 并行計算&#xff1a;14 Python 異步編程-協程的管理和調度 摘要&#xff1a; Python 異步編程基于 async/await 構建協程&#xff0c;運行在事件循環中。協程生成 Task&#xff0c;遇到?await?時掛起&#xff0c;I/O 完成觸發回調恢復運行&#xff0c;通過…

Node.js面試題及詳細答案120題(16-30) -- 核心模塊篇

《前后端面試題》專欄集合了前后端各個知識模塊的面試題&#xff0c;包括html&#xff0c;javascript&#xff0c;css&#xff0c;vue&#xff0c;react&#xff0c;java&#xff0c;Openlayers&#xff0c;leaflet&#xff0c;cesium&#xff0c;mapboxGL&#xff0c;threejs&…

RabbitMQ:Windows版本安裝部署

目錄一、概述二、OPT三、安裝RabbitMQ四、登錄測試一、概述 什么是MQ&#xff0c;有什么做作用&#xff1f; MQ即MessageQueue&#xff0c;消息隊列。可以分為兩部分理解&#xff1a;消息Message用于在不同的應用程序中傳遞數據。隊列Queue&#xff0c;一種FIFO先進先出的數據…

酒店行業安全體系構建與優化策略

酒店行業安全體系構建與優化策略為確保酒店行業領導及賓客的安全&#xff0c;構建全面的治安聯防體系及事故處理預案至關重要。某招待所通過設立保衛部&#xff0c;細化內保、治安、防火及交通管理職能&#xff0c;并下設警衛班、監控中心和電瓶車班&#xff0c;以全方位保障安…

python30-正則表達式

在Python中需要通過正則表達式對字符串進?匹配的時候&#xff0c;可以使??個python自帶的模塊&#xff0c;名字為re。 re模塊的使用&#xff1a;import re 一、匹配函數 1-1、re.match函數&#xff1a;返回匹配對象 match函數實現的是精準匹配&#xff0c;嘗試從字符串的…

EP1C12F324I7N Altera Cyclone FPGA

EP1C12F324I7N 是 阿爾特拉 Altera Cyclone 系列中的一款 SRAM-based FPGA&#xff0c;定位為低成本、低功耗、面向嵌入式與消費/工業類量產應用的器件。該器件提供約 12,060 個邏輯單元&#xff08;Logic Elements&#xff09;&#xff0c;片上嵌入式存儲約 234 kbit&#xff…

html5語義元素

1、參考&#xff1a;HTML5 語義元素 | 菜鳥教程 2、實戰 HTML5 <section> 元素 <section> 標簽定義文檔中的節&#xff08;section、區段&#xff09;。比如章節、頁眉、頁腳或文檔中的其他部分。 根據W3C HTML5文檔: section 包含了一組內容及其標題。 <!D…

java調用PyTorch 訓練模型實現神經網絡全流程

以下是完整的操作流程:用 PyTorch 訓練模型 → 導出為 ONNX 格式 → 用 Java 加載并推理,兼顧開發效率(PyTorch 快速訓練)和生產部署(Java 穩定運行)。 一、PyTorch 訓練模型并導出為 ONNX 1. 安裝依賴 bash pip install torch onnx # PyTorch 和 ONNX 庫2. 訓練一個…

Maven - Spring Boot 項目打包本地 jar 的 3 種方法

文章目錄Pre概述方案思路構建流程圖工作機制說明目錄結構示例POM 配置模板構建與驗證注意事項方案優缺點Pre Maven - Manual Maven JAR Installation&#xff1a;用 mvn install:install-file 安裝本地 JAR 的實用指南 概述 在 Spring Boot 項目中&#xff0c;通常依賴包會從…

平替 Claude Code,API接入 GPT-5,Codex CLI 國內直接使用教程

最新升級接入GPT-5的 Codex 擁有可以媲美 Claude Code 的AI編碼能力&#xff0c;本文將指導你在 Windows系統上部署原生的 Codex CLI程序&#xff0c;并且接入超低價中轉API&#xff0c;讓你在國內直接用上超高性價比的 OpenAI Codex CLI 應用。關于 CodexCodex 是 OpenAI 開發…

kubernertes (K8S)部署

參考&#xff1a; https://blog.csdn.net/yu33575/article/details/135387548 二進制安裝k8s&#xff1a; https://blog.csdn.net/qq_73990369/article/details/143217084 K8S二進制安裝與部署 &#xff1a;https://blog.csdn.net/fantuan_sss/article/details/139073366 k8s…

LeetCode 簡單JS刷題

目錄 返回數組最后一個元素 2787.將一個數字表示成冪的和的方案數 326.3的冪 1780.判斷一個數字是否可以表示成三的冪的和 342.4的冪 返回數組最后一個元素 1.請你編寫一段代碼實現一個數組方法&#xff0c;使任何數組都可以調用 array.last() 方法&#xff0c;這個方法將…

七大排序算法全解析:從入門到精通

目錄 一.排序的概念 二.常見排序算法的實現 2.1 插入排序 &#xff08;1&#xff09;直接插入排序&#xff1a; 當插入第i(i>1)個元素時&#xff0c;前面的array[0],array[1],…,array[i-1]已經排好序&#xff0c;此時用array[i]的排序碼與array[i-1],array[i-2],…的排序…

20250814在榮品RD-RK3588開發板的Android13下解決卡迪的LCD屏在開機的時候brightness最暗【背光的pwm信號的極性反了】

20250814在榮品RD-RK3588開發板的Android13下解決卡迪的LCD屏在開機的時候brightness最暗【背光的pwm信號的極性反了】 2025/8/14 11:33緣起&#xff1a;在榮品RD-RK3588開發板的Android13下&#xff0c;卡迪的LCD屏在開機的時候很暗&#xff0c;幾乎看不見。 在命令行查看亮度…

Flink的狀態管理

一、狀態的概念Flink的狀態其實你就可以將其想象為中間結果就可以了。在Flink中&#xff0c;算子的任務可以分為無狀態和有狀態兩種情況。無狀態算子任務在計算過程中是不依賴于其他數據的&#xff0c;只根據當前的輸入數據就可以得到結果輸出。比如之前講到的Map、FlatMap、Fi…

GoLand 項目從 0 到 1:第八天 ——GORM 命名策略陷阱與 Go 項目啟動慢問題攻堅

第八天核心任務&#xff1a;解決開發中的兩大技術卡點今天的開發不僅聚焦于代碼層面的數據庫字段映射問題&#xff0c;還遭遇了一個困擾團隊許久的環境難題 ——Go 項目啟動異常緩慢。經過多維度排查&#xff0c;我們不僅理清了 GORM 命名策略的設計邏輯&#xff0c;還找到了影…

在Ubuntu上安裝Google Chrome的詳細教程

步驟 1&#xff1a;下載 Google Chrome 安裝包 打開瀏覽器輸入https://www.google.cn/chrome/&#xff0c;然后進入Chrome瀏覽器官方網站 點擊下載選擇Debian/Ubuntu版本 google-chrome-stable_current_amd64.deb步驟 2&#xff1a;安裝下載的.deb 包 sudo dpkg -i google-chro…

el-table合并相同名稱的行

el-table合并相同名稱的行 <template><el-table:data"tableData":span-method"objectSpanMethod"border><el-table-columnprop"name"label"名稱"width"180"></el-table-column><el-table-column…

解決 VSCode 無法從右鍵菜單“通過 Code 打開”文件夾的問題

&#x1f9e9; 一、問題現象 VSCode 已安裝&#xff0c;但右鍵文件夾/桌面空白處無“通過 Code 打開在 VSCode 中執行 Shell Command: Install ‘Open with Code’ 無反應手動添加后菜單顯示亂碼&#xff08;如 €?? Code ‰“€&#xff09;點擊右鍵菜單無響應或提示“找不到…

服務器數據恢復—服務器硬盤狀態燈變紅,分區數據恢復過程

服務器數據恢復環境&故障&#xff1a; 某公司服務器上有一組由3塊硬盤組建的raid5磁盤陣列。 服務器上1塊硬盤的狀態燈變為紅色&#xff0c;磁盤陣列出現故障&#xff0c;分區無法識別。服務器數據恢復過程&#xff1a; 1、將故障服務器上所有磁盤編號后取出。經過初檢&…