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

JVM中ClassLoader類(lèi)加載器的深入理解

 更新時(shí)間:2021年05月10日 09:53:20   作者:殺手不太冷!  
這篇文章主要給大家介紹了關(guān)于JVM中ClassLoader類(lèi)加載器的相關(guān)資料,文中通過(guò)圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

JVM的體系結(jié)構(gòu)圖

先來(lái)看一下JVM的體系結(jié)構(gòu),如下圖:

img

JVM的位置

JVM的位置,如下圖:

img

JVM是運(yùn)行在操作系統(tǒng)之上的,與硬件沒(méi)有直接的交互,但是可以調(diào)用底層的硬件,用JIN(Java本地接口調(diào)用底層硬件)

JVM結(jié)構(gòu)圖中的class files文件

class files文件,是保存在我們電腦本地的字節(jié)碼文件,.java文件經(jīng)過(guò)編譯之后,就會(huì)生成一個(gè).class文件,這個(gè)文件就是class files所對(duì)應(yīng)的字節(jié)碼文件,如下圖:

JVM結(jié)構(gòu)圖中的類(lèi)加載器ClassLoader的解釋

 類(lèi)加載器ClassLoader的作用

類(lèi)加載器只有一個(gè)作用,就是負(fù)責(zé)把我們本地的.class字節(jié)碼文件,加載到JVM中,以類(lèi)模板的形式存在于JVM中。

類(lèi)加載器加載的.class文件也是有要求的,并不是只要是后綴名為.class的文件,都可以被類(lèi)加載器加載,這個(gè).class文件的必須是.java文件經(jīng)過(guò)編譯后得到的字節(jié)碼文件,也就是指這個(gè).class文件的開(kāi)頭必須要是cafe babe字符單詞,它的內(nèi)容是經(jīng)過(guò)加密后的二進(jìn)制文件,但是此二進(jìn)制使用十六進(jìn)制表示出來(lái)的,如下圖:

類(lèi)加載器ClassLoader只負(fù)責(zé)加載.class文件,但至于他是否可以運(yùn)行,由JVM中的執(zhí)行引擎Excution Engine決定的。

img

解釋:

Car.class是由.java文件編譯得來(lái)的.class文件,存在本地磁盤(pán)。

ClassLoader:類(lèi)加載器,負(fù)責(zé)加載并初始化 類(lèi)文件,得到真正的Class類(lèi),即模板。

Car Class:由Car.class字節(jié)碼文件,通過(guò)ClassLoader加載并且初始化得到,這個(gè)Car就是當(dāng)前類(lèi)的模板,這個(gè)Car Class模板就存在方法區(qū)。

car1,car2,car3:是由Car模板經(jīng)過(guò)實(shí)例化而得,一個(gè)模板可以獲得多個(gè)實(shí)例化對(duì)象。

拿car1舉例,car1.getClass()可以得到模板Car類(lèi),Car.getClassLoader()可得到其裝載器。

類(lèi)加載器的種類(lèi)

一共有四類(lèi)。

虛擬機(jī)自帶的加載器:

啟動(dòng)類(lèi)加載器,也叫根加載器(BootStrap)。由C++編寫(xiě),程序中自帶的類(lèi),存儲(chǔ)在 $JAVAHOME/jre/lib/rt.jar中,如object類(lèi)等

擴(kuò)展類(lèi)加載器(Extension),Java編寫(xiě),在我們看到的類(lèi)路徑中,凡是以Javax開(kāi)頭的,都是拓展包,存儲(chǔ)在 $JAVAHOME/jre/lib/ext/*.jar 中,為什么會(huì)有擴(kuò)展包?是因?yàn)樵镜膉ava包中在功能上,不能滿足我們了,所以我們就在原本的java包的基礎(chǔ)上擴(kuò)展出了一些新的功能,而形成的新的包就叫做擴(kuò)展包。

應(yīng)用程序類(lèi)加載器(AppClassLoader),即平時(shí)程序中自定義的類(lèi) new出來(lái)的

用戶自定義的加載器:

Java.lang.ClassLoader的子類(lèi),用戶可以定制類(lèi)的加載方式,即如果你的程序有特殊的需求,你也可以自定義你的類(lèi)加載器的加載方式 ,進(jìn)入ClassLoader的源碼,其為抽象類(lèi),因此在你定制化開(kāi)發(fā)的時(shí)候,需要你定義自己的加載器類(lèi)來(lái)繼承ClassLoader抽象類(lèi)即可,即 MyClassLoader extends ClassLoader

java類(lèi)的加載機(jī)制

首先你需要知道,當(dāng)java程序需要加載一個(gè)類(lèi)的時(shí)候,會(huì)去找類(lèi)加載器,然后找類(lèi)加載器里面看是否有對(duì)應(yīng)的類(lèi)模板。

Java的類(lèi)加載機(jī)制,永遠(yuǎn)是以 根加載器->拓展類(lèi)加載器->應(yīng)用程序類(lèi)加載器 這樣的一個(gè)順序進(jìn)行加載的。什么意思呢?就是如果能在BootStrapClassLoader類(lèi)加載器的路徑下找到對(duì)應(yīng)的類(lèi)模板,那么就不會(huì)再去擴(kuò)展類(lèi)加載器ExtensionClassLoader中找對(duì)應(yīng)的類(lèi)模板,如果能在擴(kuò)展類(lèi)加載器ExtensionClassLoader中找到對(duì)應(yīng)的類(lèi)模板,那么就不會(huì)去應(yīng)用程序類(lèi)加載器AppClassLoader中找對(duì)應(yīng)的類(lèi)模板。類(lèi)加載器的父子級(jí)關(guān)系,如下圖:

img

從上圖可以看出根加載器BootStrapClassLoader是擴(kuò)展類(lèi)加載器ExtensionClassLoader的父級(jí),擴(kuò)展類(lèi)加載器ExtensionClassLoader是應(yīng)用程序加載器AppClassLoader的父級(jí),如下圖:

被某個(gè)類(lèi)加載器加載的類(lèi),都會(huì)存放到這個(gè)類(lèi)加載器的路徑中,當(dāng)程序需要加載某個(gè)類(lèi)的時(shí)候,會(huì)先去根加載器BootstrapClassLoader的路徑下,尋找是否有這個(gè)類(lèi)的模板,如果沒(méi)有則會(huì)去這個(gè)類(lèi)加載器的下一級(jí),若有,則不會(huì)再去下一級(jí)尋找了。

利用obj.getClass().getClassLoader()方法,可以找到對(duì)應(yīng)的類(lèi)模板是存放在哪個(gè)類(lèi)加載器的路徑下的,換一個(gè)說(shuō)法,可以讓你知道在加載這個(gè)類(lèi)模板所對(duì)應(yīng)的類(lèi)的字節(jié)碼文件的時(shí)候,是用的哪一個(gè)類(lèi)加載器把這個(gè)類(lèi)的字節(jié)碼文件加載成類(lèi)模板的,如下圖:

那么問(wèn)題來(lái)了?為什么說(shuō)Object類(lèi)是java自帶的類(lèi)呢?java自帶的類(lèi)到底可以在哪里找到呢?java自帶的類(lèi)可以 J A V A H O M E / j r e / l i b / r t . j a r 下 找 到 。 首 先 來(lái) 看 一 下 JAVAHOME/jre/lib/rt.jar下找到。首先來(lái)看一下 JAVAHOME/jre/lib/rt.jar下找到。首先來(lái)看一下JAVAHOME,也即是java的安裝目錄,如下圖:

然后咱來(lái)看一下$JAVAHOME/jre/lib/rt.jar中的包(rt其實(shí)也即是RunTime的縮寫(xiě)),如下圖:

打開(kāi)rt.jar壓縮包,它的目錄結(jié)構(gòu),如下圖:

Object類(lèi)在java/lang包下,如下圖:

JVM中的類(lèi)加載器,根加載器BootStrap,在一開(kāi)始,就會(huì)把rt.jar壓縮包中的所有的 類(lèi)的字節(jié)碼文件都加載到JVM中,變成類(lèi)的模板,所以這些java自帶的類(lèi),對(duì)應(yīng)的類(lèi)的模板,都會(huì)被存放到根加載器BootStrap的路徑下面。故當(dāng)java程序中需要用到j(luò)ava中的自帶類(lèi)的時(shí)候,都會(huì)去根加載器BootStrap的路徑下去尋找類(lèi)的模板。

雙親委派機(jī)制

官方概念:當(dāng)一個(gè)類(lèi)收到類(lèi)加載請(qǐng)求后,他不會(huì)首先去加載這個(gè)類(lèi),而是把這個(gè)請(qǐng)求委派給父類(lèi)去完成。每一個(gè)層次的類(lèi)加載器都是如此,因此所有的類(lèi)加載器請(qǐng)求都是應(yīng)該傳到根加載器中的,只有當(dāng)其父類(lèi)加載器自己無(wú)法完成這個(gè)請(qǐng)求的時(shí)候(在他的加載路徑下沒(méi)有找到所需加載的class),子類(lèi)加載器才會(huì)嘗試自己去加載。

我的理解翻譯:當(dāng)java程序需要加載一個(gè)類(lèi)的時(shí)候,比如要加載java.lang.String類(lèi),會(huì)首先去根加載器類(lèi)BootstrapClassLoader的路徑下去尋找,如果在根加載器路徑下可以找到j(luò)ava.lang.String類(lèi),那么就不會(huì)再往下尋找java.lang.String類(lèi)了,因?yàn)橐呀?jīng)找到了;若在根加載器路徑下沒(méi)有找到j(luò)ava.lang.String類(lèi),則會(huì)去下一級(jí)擴(kuò)展類(lèi)加載器ExtensionClassLoader中尋找java.lang.String類(lèi),如果在擴(kuò)展類(lèi)加載器中找到了java.lang.String類(lèi),那么就不會(huì)再去下一級(jí)類(lèi)加載器中尋找了;如果沒(méi)有找到,則會(huì)去應(yīng)用程序類(lèi)加載器AppClassLoader中去尋找java.lang.String類(lèi),如果仍然沒(méi)有找到會(huì)報(bào)classNotFoundException異常。

采用雙親委派機(jī)制的好處:保證了我們寫(xiě)的代碼不會(huì)污染到j(luò)ava的源代碼,因?yàn)橹灰猨ava的源代碼中存在我們即將要加載的類(lèi),那么java程序在加載類(lèi)的時(shí)候就會(huì)去頂層的根加載器BootstrapClassLoader路徑下去尋找類(lèi)模板,然后把這個(gè)類(lèi)加載。你就比如假設(shè)我們自己寫(xiě)一個(gè)java.lang包,然后在這個(gè)包里面寫(xiě)一個(gè)String類(lèi),那么如果java源代碼中沒(méi)有java.lang.String這個(gè)類(lèi),java程序在用到這個(gè)類(lèi)加載的時(shí)候,會(huì)用到應(yīng)用程序類(lèi)加載器AppClassLoader路徑下的java.lang.String類(lèi),但是,我們都知道java源代碼中是有java.lang.String這個(gè)類(lèi)的,也即是在根加載器BootstrapClassLoader路徑下有java.lang.String這個(gè)類(lèi),所以java程序在用到這個(gè)類(lèi)加載它的時(shí)候,會(huì)加載根加載器BootstrapClassLoader路徑下的java.lang.String類(lèi),而不會(huì)去加載應(yīng)用程序類(lèi)加載器AppClassLoader下的java.lang.String類(lèi),這樣就保證了,我們?cè)趈ava程序的其它地方所用到的java.lang.String類(lèi)的方法是正確的,怎么個(gè)正確法呢?因?yàn)榘?,假設(shè)你是加載的應(yīng)用程序加載器AppClassLoader路徑里的java.lang.String類(lèi)也即是你自己寫(xiě)的String類(lèi),那么在java程序的其它地方如果使用到了源代碼java.lang.String類(lèi)里面的方法該怎么辦?這樣是不是會(huì)出錯(cuò)?這其實(shí)也就是,你寫(xiě)的代碼污染了人家寫(xiě)的源代碼。

雙親委派機(jī)制的程序理解,如下圖:

沙箱安全機(jī)制

通過(guò)雙親委派機(jī)制,類(lèi)的加載永遠(yuǎn)都是從根加載器開(kāi)始的,如果跟加載器中沒(méi)有對(duì)應(yīng)的類(lèi)模板,則會(huì)去下一級(jí)類(lèi)加載器中尋找這個(gè)類(lèi)模板,如果有的話則就不會(huì)去下一級(jí)尋找了。這樣就保證你所寫(xiě)的代碼不會(huì)污染Java自帶的源代碼,保證了沙箱的安全。

為什么說(shuō)這樣不會(huì)污染java自帶的源代碼呢?因?yàn)橹灰猨ava的源代碼中存在我們即將要加載的類(lèi),那么java程序在加載類(lèi)的時(shí)候就會(huì)去頂層的根加載器BootstrapClassLoader路徑下去尋找類(lèi)模板,然后把這個(gè)類(lèi)加載。你就比如假設(shè)我們自己寫(xiě)一個(gè)java.lang包,然后在這個(gè)包里面寫(xiě)一個(gè)String類(lèi),那么如果java源代碼中沒(méi)有java.lang.String這個(gè)類(lèi),java程序在用到這個(gè)類(lèi)加載的時(shí)候,會(huì)用到應(yīng)用程序類(lèi)加載器AppClassLoader路徑下的java.lang.String類(lèi),但是,我們都知道java源代碼中是有java.lang.String這個(gè)類(lèi)的,也即是在根加載器BootstrapClassLoader路徑下有java.lang.String這個(gè)類(lèi),所以java程序在用到這個(gè)類(lèi)加載它的時(shí)候,會(huì)加載根加載器BootstrapClassLoader路徑下的java.lang.String類(lèi),而不會(huì)去加載應(yīng)用程序類(lèi)加載器AppClassLoader下的java.lang.String類(lèi),這樣就保證了,我們?cè)趈ava程序的其它地方所用到的java.lang.String類(lèi)的方法是正確的,怎么個(gè)正確法呢?因?yàn)榘?,假設(shè)你是加載的應(yīng)用程序加載器AppClassLoader路徑里的java.lang.String類(lèi)也即是你自己寫(xiě)的String類(lèi),那么在java程序的其它地方如果使用到了源代碼java.lang.String類(lèi)里面的方法該怎么辦?這樣是不是會(huì)出錯(cuò)?這其實(shí)也就是,你寫(xiě)的代碼污染了人家寫(xiě)的源代碼。

總結(jié)

到此這篇關(guān)于JVM中ClassLoader類(lèi)加載器的文章就介紹到這了,更多相關(guān)JVM中ClassLoader類(lèi)加載器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 指定jdk啟動(dòng)jar包的方法總結(jié)

    指定jdk啟動(dòng)jar包的方法總結(jié)

    這篇文章主要給大家總結(jié)介紹了關(guān)于指定jdk啟動(dòng)jar包的方法,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2023-07-07
  • 一問(wèn)詳解SpringBoot配置文件優(yōu)先級(jí)

    一問(wèn)詳解SpringBoot配置文件優(yōu)先級(jí)

    在SpringBoot項(xiàng)目當(dāng)中,我們要想配置一個(gè)屬性,可以通過(guò)這三種方式當(dāng)中的任意一種來(lái)配置都可以,那么優(yōu)先級(jí)怎么算,本文主要介紹了一問(wèn)詳解SpringBoot配置文件優(yōu)先級(jí),需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • 使用SpringBoot讀取Windows共享文件的代碼示例

    使用SpringBoot讀取Windows共享文件的代碼示例

    在現(xiàn)代企業(yè)環(huán)境中,文件共享是一個(gè)常見(jiàn)的需求,Windows共享文件夾(SMB/CIFS協(xié)議)因其易用性和廣泛的兼容性,成為了許多企業(yè)的首選,在Java應(yīng)用中,尤其是使用Spring Boot框架時(shí),如何讀取Windows共享文件是一個(gè)值得探討的話題,本文介紹了使用SpringBoot讀取Windows共享文件
    2024-11-11
  • Java利用happen-before規(guī)則如何實(shí)現(xiàn)共享變量的同步操作詳解

    Java利用happen-before規(guī)則如何實(shí)現(xiàn)共享變量的同步操作詳解

    這篇文章主要給大家介紹了關(guān)于Java利用happen-before規(guī)則實(shí)現(xiàn)共享變量的同步操作的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用java具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2018-06-06
  • Springboot打包部署項(xiàng)目的過(guò)程詳解

    Springboot打包部署項(xiàng)目的過(guò)程詳解

    這篇文章主要介紹了Springboot打包部署項(xiàng)目的過(guò)程,通過(guò)jar包方式打包和war方式打包,本文結(jié)合示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2023-12-12
  • 搞懂Java線程池

    搞懂Java線程池

    這篇文章主要介紹了Java線程池,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • Spring?Boot整合Zookeeper實(shí)現(xiàn)分布式鎖的場(chǎng)景分析

    Spring?Boot整合Zookeeper實(shí)現(xiàn)分布式鎖的場(chǎng)景分析

    這篇文章主要介紹了Spring?Boot整合Zookeeper實(shí)現(xiàn)分布式鎖,zk實(shí)現(xiàn)分布式鎖完全是依靠zk節(jié)點(diǎn)類(lèi)型當(dāng)中的臨時(shí)序號(hào)節(jié)點(diǎn)來(lái)實(shí)現(xiàn)的,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-06-06
  • java spring整合junit操作(有詳細(xì)的分析過(guò)程)

    java spring整合junit操作(有詳細(xì)的分析過(guò)程)

    這篇文章主要介紹了java spring整合junit操作(有詳細(xì)的分析過(guò)程),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-08-08
  • SpringBoot實(shí)現(xiàn)跨域的幾種常用方式總結(jié)

    SpringBoot實(shí)現(xiàn)跨域的幾種常用方式總結(jié)

    跨域是指一個(gè)域下的文檔或腳本試圖去請(qǐng)求另一個(gè)域下的資源,或者涉及到兩個(gè)不同域名的資源之間的交互,由于同源策略(Same Origin Policy)的限制,瀏覽器不允許跨域請(qǐng)求,本文小編給大家分享了SpringBoot實(shí)現(xiàn)跨域的幾種常用方式,需要的朋友可以參考下
    2023-09-09
  • idea中使用git插件回滾代碼的流程步驟

    idea中使用git插件回滾代碼的流程步驟

    使用idea開(kāi)發(fā)java代碼時(shí),如果想回滾git提交的代碼, 需要操作三步,本篇步驟操作前,前提是你的電腦已經(jīng)安裝了git插件,并且你的idea也集成了git插件,下面是詳細(xì)步驟,需要的朋友可以參考下
    2025-04-04

最新評(píng)論

鸡西市| 清镇市| 沾化县| 武强县| 宕昌县| 富顺县| 灵川县| 松阳县| 巨野县| 稷山县| 涿鹿县| 栾川县| 图木舒克市| 班戈县| 日照市| 越西县| 广昌县| 湖北省| 醴陵市| 清镇市| 青海省| 克东县| 巨鹿县| 雷山县| 衡山县| 定兴县| 察雅县| 纳雍县| 肇州县| 陵水| 吴旗县| 个旧市| 平凉市| 浦北县| 柳林县| 高密市| 定兴县| 沁阳市| 井陉县| 漠河县| 武安市|