最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java類加載機(jī)制從.class文件到JVM運(yùn)行時(shí)

 更新時(shí)間:2025年12月02日 08:45:10   作者:RTower  
本文詳細(xì)介紹了Java類加載機(jī)制,包括Java程序的運(yùn)行流程、類的生命周期與類加載、類加載器和雙親委派模型,通過(guò)類加載器將.class文件加載到內(nèi)存中,并轉(zhuǎn)換為JVM可以使用的運(yùn)行時(shí)數(shù)據(jù)結(jié)構(gòu),最終實(shí)現(xiàn)類的初始化,感興趣的朋友跟隨小編一起看看吧

首先先貼上一張Java類加載的思維導(dǎo)圖

一、Java 程序運(yùn)行流程

在Java中,一個(gè)程序的起點(diǎn)是.java源文件,它經(jīng)由javac編譯器編譯為字節(jié)碼.class文件。隨后,Java虛擬機(jī)(JVM)負(fù)責(zé)加載這些字節(jié)碼文件,并將其轉(zhuǎn)換為與操作系統(tǒng)交互的機(jī)器指令來(lái)執(zhí)行。我們可以用以下流程圖來(lái)概括這個(gè)宏觀過(guò)程:

二、類的生命周期與類加載

而我們今天要深入剖析的,正是JVM將.class文件中的二進(jìn)制數(shù)據(jù)讀入內(nèi)存,并轉(zhuǎn)換成JVM可以使用的運(yùn)行時(shí)數(shù)據(jù)結(jié)構(gòu)的整個(gè)過(guò)程——類加載。要理解類加載,就離不開(kāi)類的完整生命周期。下圖展示了包含類生命周期的完整視圖:

從上圖可見(jiàn),我們通常所說(shuō)的“類加載”是一個(gè)廣義概念,它主要指生命周期中“加載”和“連接”兩大階段,具體可細(xì)分為以下五個(gè)核心部分:

  • 加載
    • 加載是“類加載”過(guò)程的第一步。主要完成三件事:
  • 注意:Class文件的來(lái)源非常廣泛,不僅僅是本地文件系統(tǒng),還可以來(lái)自ZIP/JAR包、網(wǎng)絡(luò)、運(yùn)行時(shí)計(jì)算生成(動(dòng)態(tài)代理)或其它文件(JSP生成)等。

    • 通過(guò)類的全限定名獲取定義此類的二進(jìn)制字節(jié)流。
    • 將這個(gè)字節(jié)流所代表的靜態(tài)存儲(chǔ)結(jié)構(gòu)轉(zhuǎn)換為方法區(qū)的運(yùn)行時(shí)數(shù)據(jù)結(jié)構(gòu)。
    • 在內(nèi)存中生成一個(gè)代表這個(gè)類的java.lang.Class對(duì)象,作為方法區(qū)該類的各種數(shù)據(jù)的訪問(wèn)入口。
  • 驗(yàn)證
    • 驗(yàn)證是連接階段的第一步,目的是確保Class文件的字節(jié)流信息符合JVM規(guī)范,不會(huì)危害JVM自身安全。它包含四個(gè)檢驗(yàn)動(dòng)作:
  • 文件格式驗(yàn)證:驗(yàn)證字節(jié)流是否符合Class文件格式規(guī)范(如魔數(shù)、主次版本號(hào)等),這一步在加載階段即可發(fā)生。
  • 元數(shù)據(jù)驗(yàn)證:對(duì)字節(jié)碼描述的信息進(jìn)行語(yǔ)義分析,確保符合Java語(yǔ)言規(guī)范(如是否有父類、是否繼承了final類等)。
  • 字節(jié)碼驗(yàn)證:通過(guò)數(shù)據(jù)流和控制流分析,確定程序語(yǔ)義是合法的、符合邏輯的(如保證跳轉(zhuǎn)指令不會(huì)跳轉(zhuǎn)到方法體以外的字節(jié)碼上)。
  • 符號(hào)引用驗(yàn)證:發(fā)生在解析階段,確保解析動(dòng)作能正常執(zhí)行(如通過(guò)全限定名能找到對(duì)應(yīng)的類、訪問(wèn)性是否合法等)。
  • 準(zhǔn)備
    • 準(zhǔn)備階段是正式為類變量(被static修飾的變量) 分配內(nèi)存并設(shè)置初始值的階段。這些變量所使用的內(nèi)存都在方法區(qū)中進(jìn)行分配。
  • 重要概念:此階段設(shè)置的通常是數(shù)據(jù)類型的零值。例如,public static int value = 123;,在準(zhǔn)備階段后,value的初始值是0,而非123。將value賦值為123putstatic指令是在程序編譯后,存放于<clinit>()類構(gòu)造器方法中,所以賦值的動(dòng)作是在初始化階段才會(huì)執(zhí)行。
  • 特殊情況:如果類字段的字段屬性表中存在ConstantValue屬性(即被static final修飾的常量),那么在準(zhǔn)備階段變量便會(huì)被初始化為指定的值。例如,public static final int value = 123;在準(zhǔn)備階段后,value的值就是123
  • 解析
    • 解析階段是JVM將常量池內(nèi)的符號(hào)引用替換為直接引用的過(guò)程。
  • 符號(hào)引用:以一組符號(hào)來(lái)描述所引用的目標(biāo),與JVM實(shí)現(xiàn)的內(nèi)存布局無(wú)關(guān)。
  • 直接引用:可以是直接指向目標(biāo)的指針、相對(duì)偏移量或能間接定位到目標(biāo)的句柄,與JVM的內(nèi)存布局相關(guān)。
  • 解析策略
  • 靜態(tài)解析:如果符號(hào)引用在加載時(shí)就已經(jīng)明確具體的目標(biāo),那么在解析階段就可以完成替換。
  • 動(dòng)態(tài)解析:對(duì)于一些在編譯期無(wú)法確定的引用(如多態(tài)、接口實(shí)現(xiàn)),則要推遲到第一次實(shí)際使用時(shí)(運(yùn)行時(shí))再完成解析。
  • 初始化
    • 這是類加載過(guò)程的最后一步。此階段才真正開(kāi)始執(zhí)行類中定義的Java程序代碼(或字節(jié)碼)。JVM會(huì)執(zhí)行<clinit>()方法,該方法是由編譯器自動(dòng)收集類中的所有類變量的賦值動(dòng)作靜態(tài)語(yǔ)句塊中的語(yǔ)句合并產(chǎn)生的。JVM會(huì)保證在子類的<clinit>()方法執(zhí)行前,父類的<clinit>()方法已經(jīng)執(zhí)行完畢。

三、Java類加載器

類加載器是實(shí)現(xiàn)“通過(guò)一個(gè)類的全限定名來(lái)獲取描述該類的二進(jìn)制字節(jié)流”這個(gè)動(dòng)作的代碼模塊。

JVM提供了三層類加載器,它們之間以組合關(guān)系協(xié)同工作:

  • 啟動(dòng)類加載器(Bootstrap Class Loader) :
    • 由C++實(shí)現(xiàn),是JVM自身的一部分。
    • 負(fù)責(zé)加載<JAVA_HOME>/lib目錄下,或被-Xbootclasspath參數(shù)指定的路徑中的核心類庫(kù)(如rt.jar、charsets.jar等)。
    • 它是所有類加載器的父加載器。
  • 擴(kuò)展類加載器(Extension Class Loader) :
    • 由Java實(shí)現(xiàn),是sun.misc.Launcher$ExtClassLoader類。
    • 負(fù)責(zé)加載<JAVA_HOME>/lib/ext目錄下,或java.ext.dirs系統(tǒng)變量所指定的路徑中的所有類庫(kù)。
    • 它是應(yīng)用程序類加載器的父加載器。
  • 應(yīng)用程序類加載器(Application Class Loader) :
    • 由Java實(shí)現(xiàn),是sun.misc.Launcher$AppClassLoader類。
    • 負(fù)責(zé)加載用戶類路徑(ClassPath)上所指定的類庫(kù)。它是程序中默認(rèn)的類加載器。

除了這三個(gè)系統(tǒng)提供的類加載器,用戶還可以通過(guò)繼承java.lang.ClassLoader類的方式,定制自己的類加載器,以滿足特殊的需求(如熱部署、從網(wǎng)絡(luò)或加密文件中加載類等)。

四、雙親委派模型

1. 工作流程

雙親委派模型要求除了頂層的啟動(dòng)類加載器外,其余的類加載器都應(yīng)有自己的父類加載器(這里的父子關(guān)系一般通過(guò)組合而非繼承來(lái)實(shí)現(xiàn))。它的工作流程是:

當(dāng)一個(gè)類加載器收到了類加載請(qǐng)求,它首先不會(huì)自己去嘗試加載這個(gè)類,而是把這個(gè)請(qǐng)求委派給父類加載器去完成。每一層的類加載器都是如此,因此所有的加載請(qǐng)求最終都應(yīng)該傳送到頂層的啟動(dòng)類加載器中。

只有當(dāng)父類加載器反饋?zhàn)约簾o(wú)法完成這個(gè)加載請(qǐng)求(它的搜索范圍中沒(méi)有找到所需的類)時(shí),子加載器才會(huì)嘗試自己去加載。

2. 核心優(yōu)勢(shì)

  • 避免類的重復(fù)加載:確保一個(gè)類在JVM中全局唯一。父加載器加載過(guò)了,子加載器就不會(huì)再加載一次。
  • 保證程序安全:防止核心API庫(kù)被隨意篡改。例如,用戶自定義一個(gè)java.lang.Object類,雙親委派機(jī)制會(huì)保證最終由啟動(dòng)類加載器加載核心的Object類,而用戶自定義的Object類不會(huì)被加載,從而防止了惡意代碼的注入。

3. 破壞雙親委派模型

雙親委派模型并非強(qiáng)制性約束。在某些場(chǎng)景下它會(huì)被打破,例如:

  • SPI(Service Provider Interface)機(jī)制:如JDBC。核心接口在rt.jar中由啟動(dòng)類加載器加載,但具體實(shí)現(xiàn)(如MySQL驅(qū)動(dòng))在ClassPath下,需要由應(yīng)用類加載器加載。這就引入了線程上下文類加載器來(lái)逆向委托子加載器去加載實(shí)現(xiàn)類。
  • OSGi、JNDI等模塊化熱部署技術(shù),也需要?jiǎng)討B(tài)調(diào)整類加載器的委托關(guān)系。

到此這篇關(guān)于Java類加載機(jī)制從.class文件到JVM運(yùn)行時(shí)的文章就介紹到這了,更多相關(guān)java類加載機(jī)制內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring Cloud Feign組成配置過(guò)程解析

    Spring Cloud Feign組成配置過(guò)程解析

    這篇文章主要介紹了Spring Cloud Feign組成配置過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • java求100以內(nèi)的素?cái)?shù)示例分享

    java求100以內(nèi)的素?cái)?shù)示例分享

    素?cái)?shù)是指因數(shù)只有1和本身的數(shù)字,這篇文章主要介紹了java求100以內(nèi)的素?cái)?shù)示例,需要的朋友可以參考下
    2014-03-03
  • 使用Java實(shí)現(xiàn)價(jià)格加密與優(yōu)化功能

    使用Java實(shí)現(xiàn)價(jià)格加密與優(yōu)化功能

    在現(xiàn)代軟件開(kāi)發(fā)中,數(shù)據(jù)加密是一個(gè)非常重要的環(huán)節(jié),尤其是在處理敏感信息(如價(jià)格、用戶數(shù)據(jù)等)時(shí),本文將詳細(xì)介紹如何使用?Java?實(shí)現(xiàn)價(jià)格加密,并對(duì)代碼進(jìn)行優(yōu)化,需要的朋友可以參考下
    2025-01-01
  • 淺談將子類對(duì)象賦值給父類對(duì)象

    淺談將子類對(duì)象賦值給父類對(duì)象

    淺談將子類對(duì)象賦值給父類對(duì)象...
    2006-12-12
  • javaweb實(shí)現(xiàn)文件上傳功能

    javaweb實(shí)現(xiàn)文件上傳功能

    這篇文章主要為大家詳細(xì)介紹了javaweb實(shí)現(xiàn)文件上傳功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • Java多線程 生產(chǎn)者消費(fèi)者模型實(shí)例詳解

    Java多線程 生產(chǎn)者消費(fèi)者模型實(shí)例詳解

    這篇文章主要介紹了Java多線程 生產(chǎn)者消費(fèi)者模型實(shí)例詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-09-09
  • springboot整合Nacos組件環(huán)境搭建和入門案例詳解(最新推薦)

    springboot整合Nacos組件環(huán)境搭建和入門案例詳解(最新推薦)

    本文介紹了Nacos的基礎(chǔ)概念、關(guān)鍵特性、專業(yè)術(shù)語(yǔ)和生態(tài)圈,如何在Windows環(huán)境下搭建Nacos單個(gè)服務(wù),以及如何整合SpringBoot2來(lái)使用Nacos進(jìn)行服務(wù)注冊(cè)和配置管理,感興趣的朋友一起看看吧
    2025-03-03
  • java 抽象類與接口的區(qū)別介紹

    java 抽象類與接口的區(qū)別介紹

    這篇文章主要介紹了java 抽象類與接口的區(qū)別介紹的相關(guān)資料,需要的朋友可以參考下
    2016-10-10
  • 使用Spring AOP監(jiān)控指定方法執(zhí)行時(shí)間的代碼詳解

    使用Spring AOP監(jiān)控指定方法執(zhí)行時(shí)間的代碼詳解

    這篇文章主要介紹了使用Spring AOP監(jiān)控指定方法執(zhí)行時(shí)間,文中通過(guò)代碼示例給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2024-08-08
  • 深入理解JDK8中Stream使用

    深入理解JDK8中Stream使用

    Stream 是 Java8 中處理集合的關(guān)鍵抽象概念,它可以指定你希望對(duì)集合進(jìn)行的操作,可以執(zhí)行非常復(fù)雜的查找、過(guò)濾和映射數(shù)據(jù)等操作。這篇文章主要介紹了JDK8中Stream使用解析,需要的朋友可以參考下
    2021-06-06

最新評(píng)論

五寨县| 沁源县| 潢川县| 蓝田县| 法库县| 新邵县| 沁阳市| 金塔县| 沾化县| 凉城县| 杭州市| 泗水县| 惠东县| 大荔县| 邢台县| 江城| 桐乡市| 资溪县| 小金县| 江门市| 武穴市| 七台河市| 海口市| 龙南县| 左云县| 阜康市| 温州市| 浮山县| 新田县| 聊城市| 西宁市| 新泰市| 虹口区| 托克逊县| 剑河县| 周口市| 尼木县| 通榆县| 林周县| 酉阳| 阳谷县|