1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        從源碼理解類加載

        共 3370字,需瀏覽 7分鐘

         ·

        2021-07-14 22:25

        點(diǎn)擊上方藍(lán)色字體,選擇“標(biāo)星公眾號(hào)”

        優(yōu)質(zhì)文章,第一時(shí)間送達(dá)

        從源碼理解類加載

              我們都知道,我們得java程序得運(yùn)行,實(shí)際是根據(jù)面向?qū)ο缶幊痰迷?,為一個(gè)個(gè)類創(chuàng)建對(duì)象,對(duì)象們協(xié)同工作,完成了程序得運(yùn)行!

              但是這些類,說(shuō)到底是一個(gè)個(gè)得文件,二進(jìn)制的class,如何變成為jvm所用的對(duì)象呢?,我們稱之為類加載!看classloader偶有心得,隨筆以記!

         

        1  類加載原理(雙親委派機(jī)制)

             說(shuō)到雙親委派機(jī)制,那就祭出一張十分眼熟得圖!

         

         

                這是一張很簡(jiǎn)單易懂得圖!就是類加載是有父子關(guān)系得,當(dāng)接受到類加載請(qǐng)求時(shí),都是先去找自己得“爸爸”類加載去完成加載,找到則返回,找不到則跑錯(cuò)!可參考下圖源碼理解:

         

                上圖得這段代碼就是classload種得loadClass方法實(shí)現(xiàn)!上圖可見(jiàn),根據(jù)一個(gè)name加載類時(shí),第一步會(huì)根據(jù)name得到一個(gè)鎖,保證類加載得并發(fā)安全!第二步就是判斷父類加載器是否為空,如果不為空,這調(diào)用父類加載得loadClass方法加載,如果為空,則第三步使用根加載器BootStrap根據(jù)名稱加載,如果以上步驟完成后,依然沒(méi)加載到類,在第四步調(diào)用findClass(name),實(shí)際是拋出一個(gè) ClassNotFoundException(name)的異常!

               類加載器主要有四種,根加載,擴(kuò)展加載,應(yīng)用加載,自定義加載,其父子順序主要可見(jiàn) sun.misc.Lancher中代碼:

         

                在Lancher的構(gòu)造函數(shù)中,首先創(chuàng)建了ExtClassLoader 擴(kuò)展加載,沒(méi)有傳遞parent加載器,則為根加載器BootStrap加載器為parent,而后又將ExtClassLoader 做為parent屬性,用以創(chuàng)建了AppClassLoader應(yīng)用加載!

               在Lancher中有一個(gè)根目錄屬性 bootClassPath,通過(guò) System.getProperty("sun.boot.class.path"); 如果將其打印,可以發(fā)現(xiàn)是jdk下的lib下的一些jar包和classee目錄!在Lancher中的靜態(tài)內(nèi)部類ExtClassLoader 實(shí)現(xiàn)了擴(kuò)展加載,在調(diào)用getExtClassLoader時(shí)會(huì)調(diào)用createExtClassLoader方法給單例模式的ExtClassLoader  instrance創(chuàng)建,在createExtClassLoader方法中可見(jiàn)調(diào)用了 getExtDirs()方法,實(shí)際是通過(guò)System.getProperty("java.ext.dirs")獲取擴(kuò)展加載的類,打印可見(jiàn)該目錄是jre\lib\ext目錄。

              在Lancher的靜態(tài)內(nèi)部類 AppClassLoader中實(shí)現(xiàn)了應(yīng)用加載,在調(diào)用 getAppClassLoader方法獲取應(yīng)用加載器的代碼中可見(jiàn)調(diào)用了System.getProperty("java.class.path") 獲取了開(kāi)發(fā)人員指定的resource路徑或默認(rèn)路徑。

              在這個(gè)完整的模式下,加載的類可以被它的類加載器緩存,沒(méi)必要重復(fù)加載,同時(shí),如果定義了同一個(gè)名稱的兩個(gè)類,也只會(huì)加載一個(gè),保證了安全。

              通過(guò)閱讀ClassLoader的代碼可見(jiàn),自定義類加載,實(shí)現(xiàn)ClassLoader即可,通過(guò)調(diào)用loadclass實(shí)現(xiàn)類加載!如果想打破雙親委派加載模型,在自己重寫的loadClass方法中實(shí)現(xiàn)即可。

             那么把一個(gè)class文件從jar包中讀取生成class對(duì)象,又可見(jiàn)以下圖:

         

               加載: 通過(guò)類的全限定名獲取二進(jìn)制字節(jié)流,把這個(gè)字節(jié)流代表的靜態(tài)存儲(chǔ)結(jié)構(gòu)轉(zhuǎn)化為方法區(qū)的運(yùn)行時(shí)數(shù)據(jù)接口,在內(nèi)存中創(chuàng)建一個(gè)Class對(duì)象作為方法區(qū)內(nèi)這個(gè)類的訪問(wèn)入口。

               驗(yàn)證:1 文件格式驗(yàn)證:

                          a  class文件以0xCAFEBABE(咖啡baby)開(kāi)頭

                          b   版本號(hào)是否在當(dāng)前虛擬機(jī)可接受范圍

                          c   常量池中常量是否有不支持的類型

                          ........

                          2 元數(shù)據(jù)驗(yàn)證 :主要是驗(yàn)證語(yǔ)義,語(yǔ)法是否復(fù)合java語(yǔ)言規(guī)范,比如 是否有父類,父類是否是被final修飾過(guò),如果不是抽象類,是否已完全實(shí)現(xiàn)抽象方法等

                          3 字節(jié)碼驗(yàn)證 : 主要是驗(yàn)證語(yǔ)義預(yù)發(fā)是否合乎邏輯,注意,是邏輯,不同2中的規(guī)范。比如long類型數(shù)據(jù)被以int加載到本地

                          4 符合引用驗(yàn)證,驗(yàn)證類中用到的引用是否自己有通過(guò)全限定名訪問(wèn)的權(quán)限

               準(zhǔn)備:為類中定義的靜態(tài)變量分配內(nèi)存

               解析:解析內(nèi)部的字段和方法,把符號(hào)引用替換為直接引用

               初始化 :靜態(tài)變量獲取到了指定句柄,既指定值,執(zhí)行靜態(tài)代碼。

         

               以上為類加載的過(guò)程,那合適會(huì)出發(fā)類加載呢?有以下條件觸發(fā):

             1  遇到new  getstatic putstatic  invokestatic四個(gè)指令時(shí),如果沒(méi)有初始化,則需要觸發(fā)初始化。這4個(gè)指令通常是new 實(shí)例化對(duì)象,讀取或設(shè)置static屬性,調(diào)用靜態(tài)方法是。

             2  對(duì)一個(gè)類使用反射包下方法調(diào)用時(shí)

             3 初始化一個(gè)類,但是發(fā)現(xiàn)起父類沒(méi)有初始化時(shí)

             4 虛擬機(jī)啟動(dòng)時(shí),執(zhí)行一個(gè)主類


          作者 |  斯人已戒

        來(lái)源 |  https://www.cnblogs.com/huqk-nn/p/15003344.html




        瀏覽 39
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            国精产品一区一区三区mba下载 | japanese一本色道久久 | 在线观看AV网站 | 欧美一区二区三区免费A片老妇人 | 操碰视频在线 | 欧美粉嫩metart69hd 毛片无遮挡高清免费观看 欧美激情一级片 | 淫香淫香 | 啊啊啊啊别操了 | 黄片免费视频大全 | 色婷婷精品在线播放 |