<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          面試官再問你如何破壞雙親委派,就把這篇文章扔給他

          共 3955字,需瀏覽 8分鐘

           ·

          2021-05-23 15:16



          前言

          我們每天都在寫Java代碼,最常見的User.java這種文件,但是這種文件是如何被虛擬機(jī)識別的呢,你有沒有思考過這個過程

          首先我們寫的Java文件會被編譯成class文件,因?yàn)闄C(jī)器不認(rèn)識getName這種,機(jī)器只認(rèn)識010101

          編譯完成的class文件會被加載到虛擬機(jī)中,用于完成我們的任務(wù),那這個加載是什么時候開始呢,加載的過程是什么樣子的呢


          類加載時機(jī)

          先來肝個圖,類的加載過程

          類從被加載到虛擬機(jī)開始,到卸載出內(nèi)存為止,它的整個的生命周期包括:加載、驗(yàn)證、準(zhǔn)備、解析、初始化、使用和卸載七個階段

          而驗(yàn)證、準(zhǔn)備、解析三個階段被統(tǒng)稱為連接階段

          類的加載時機(jī),也就是類是在何時開始加載這一過程的呢

          這一點(diǎn)虛擬機(jī)并沒有明確規(guī)范,虛擬機(jī)可以自由實(shí)現(xiàn),但是對于其中有一個步驟叫做初始化,虛擬機(jī)規(guī)范則是嚴(yán)格規(guī)定了有且只有5種情況立即對類進(jìn)行初始化,而在此之前的過程也需要提前開始

          • 遇到new、getstatic、putstatic或者invokestatic這四條字節(jié)碼指令時,生成這四個字節(jié)碼最常見的Java代碼場景就是使用new關(guān)鍵字實(shí)例化對象的時候、讀取或者設(shè)置一個類的靜態(tài)字段,以及調(diào)用一個類的靜態(tài)方法的時候

          • 使用java.lang.reflect包的方法進(jìn)行反射調(diào)用的時候,類如果沒有初始化則觸發(fā)初始化

          • 初始化一個類的時候,發(fā)現(xiàn)其父類未進(jìn)行初始化,需要先初始化父類

          • JVM啟動時用戶指定執(zhí)行包含main方法的類,會先被初始化

          • 當(dāng)使用JDK1.7的動態(tài)語言支持的時候,如果一個java.lang.invoke.MethodHandle實(shí)例最后的解析結(jié)果是REF_getStatic、REF_putStatic、REF_putStatic、REF_invokeStatic的方法句柄的時候,并且這個方法句柄所對應(yīng)的類沒進(jìn)行初始化,需要先初始化


          類加載過程

          類加載過程,其實(shí)這是屬于純理論知識,大家不知道這些工作中照常開發(fā),為什么呢,因?yàn)橐话氵@種東西在實(shí)際工作中確實(shí)也派不上什么用場

          那我看這個還有啥用啊,拜拜了您嘞

          話不是這么說的,仔仔,你不能說你用不到他就一點(diǎn)也不去了解他,有一句話叫做,書到用時方很少,多讀讀書,學(xué)學(xué)這些基礎(chǔ)知識,有利于你更好的打牢你的基礎(chǔ)

          在外面面試時也能夠神擋殺神,佛擋殺佛

          面試官還就愛問這玩意,這玩意能看出你學(xué)習(xí)的深度,有沒有自己去思考過這些東西

          類加載過程:加載、連接、初始化

          加載過程

          將編譯之后的Class文件加載至虛擬機(jī),并存儲在方法區(qū)(不知道為什么存儲在方法區(qū)的仔仔,可以去我的面試官問我平時寫的Bug的存儲位置(逃逸分析、標(biāo)量替換、鎖消除)這一篇中學(xué)一波拉

          連接過程

          連接其實(shí)也是被分為了驗(yàn)證、準(zhǔn)備、解析三部分組成,驗(yàn)證就是保證該Class文件中的信息是否符合Java虛擬機(jī)的要求,是否安全(可能會做出危害虛擬機(jī)的行為)準(zhǔn)備就是為類變量分配內(nèi)存,并設(shè)置類變量的初始值,不包含實(shí)例變量的內(nèi)存,實(shí)例變量的內(nèi)存將會被分配到堆中

          這里的初始值指的是數(shù)據(jù)類型的零值,并非程序員設(shè)置的值,比如static int i = 1;此時得到的i是0,并非我們想要的1

          接下來就是連接過程的解析階段,這一階段就是將常量池中的符號引用替換為直接引用(內(nèi)存地址)的過程

          解析階段啥玩意啊,說了個寂寞,符號引用是啥,直接引用又是啥

          符號引用,就是以一組符號來描述所引用的目標(biāo),符號可以是任何形式的字面量,只要使用的時候能夠無歧義的定位到目標(biāo)即可

          直接引用,可以直接指向目標(biāo)的指針、相對偏移量或者是一個能夠間接定位到目標(biāo)的句柄,直接引用是和內(nèi)存布局相關(guān)的,同一個符號引用在不同虛擬機(jī)翻譯出來的直接引用一般不同,因?yàn)榈刂凡灰粯?br>

          如果有了直接引用,則引用的目標(biāo)必定已經(jīng)存在于內(nèi)存中了

          初始化

          初始化是類加載的最后一步,前面的類加載過程中,除了在加載階段用戶應(yīng)用程序可以通過自定義類加載器參與之外,其余的動作其實(shí)都是由虛擬機(jī)主導(dǎo)和控制的

          而初始化階段才是真正開始執(zhí)行程序中代碼的步驟,也就是上面說的i賦值為1的過程,初始化類變量,加載類的靜態(tài)語句塊的過程

          在準(zhǔn)備階段賦值過一次了,那次賦值是系統(tǒng)要求的初始值,跟我們個人的設(shè)定無關(guān),而初始化的賦值才是真正根據(jù)程序員設(shè)計(jì)而主導(dǎo)的初始化

          使用和卸載

          使用類的階段就是大家new對象的過程,我們會使用到各種類型對象,以及使用完畢對這個類型的卸載,卸載一般發(fā)生在程序關(guān)閉的時候

          程序正常執(zhí)行結(jié)束、遇到異常關(guān)閉、或者操作系統(tǒng)出問題導(dǎo)致程序關(guān)閉這些都會卸載這些類的加載


          雙親委派

          類加載器

          從JVM的角度看,類加載器主要有兩類:

          • Bootstrap ClassLoader和其他類加載,Bootstrap ClassLoader是C++語言實(shí)現(xiàn),是虛擬機(jī)自身的一部分;

          • 其他類加載器都是Java語言實(shí)現(xiàn),不屬于虛擬機(jī),全部繼承自抽象類java.lang.ClassLoader

          從Java開發(fā)者的角度看,需要了解類加載器的雙親委派模型,如下圖所示:

          Bootstrap ClassLoader:啟動類加載器,這個類加載器將負(fù)責(zé)存放在/lib目錄中,并且是虛擬機(jī)會識別的jar類庫加載到內(nèi)存中。更直白點(diǎn)說,就是我們常用的java.lang開頭的那些類,一定是被Bootstrap ClassLoader加載的

          Extension ClassLoader:擴(kuò)展類加載器,它負(fù)責(zé)加載/lib/ext目錄中的、或者被java.ext.dirs系統(tǒng)變量指定的路徑中的所有類庫。

          Application ClassLoader:應(yīng)用程序類加載器,它負(fù)責(zé)加載用戶CLASSPATH環(huán)境變量指定的路徑中的所有類庫。如果應(yīng)用程序中沒有自定義過自己的類加載器,這個就是一個Java程序中默認(rèn)的類加載器。

          用戶自定義的類加載器:用戶在需要的情況下,可以實(shí)現(xiàn)自己的自定義類加載器,一般而言,在以下幾種情況下需要自定義類加載器

          • 隔離加載類。某些框架為了實(shí)現(xiàn)中間件和應(yīng)用程序的模塊的隔離,就需要中間件和應(yīng)用程序使用不同的類加載器

          • 修改類加載的方式。類加載的雙親委派模型并不是強(qiáng)制的,用戶可以根據(jù)需要在某個時間點(diǎn)動態(tài)加載類

          • 擴(kuò)展類加載源,例如從數(shù)據(jù)庫、網(wǎng)絡(luò)進(jìn)行類加載

          • 防止源代碼泄露。Java代碼很容易被反編譯和篡改,為了防止源碼泄露,可以對類的字節(jié)碼文件進(jìn)行加密,并編寫自定義的類加載器來加載自己的應(yīng)用程序的類

          聽說過雙親委派嗎

          至于雙親委派,我覺得可能很多人都聽說過,或者說簡單的了解過,大魚這里也繼續(xù)給大家啰嗦一下

          如果一個類加載器收到了類加載的請求,它首先不會自己去嘗試加載這個類,而是把請求委托給父加載器去完成,依次向上,因此,所有的類加載請求最終都應(yīng)該被傳遞到頂層的啟動類加載器中,只有當(dāng)父加載器在它的搜索范圍中沒有找到所需的類時,即無法完成該加載,子加載器才會嘗試自己去加載該類

          見過一個問題,說為什么叫雙親委派,而不是單親委派,在Java中應(yīng)該是單繼承的,哪里來的雙親呢

          我個人的猜測是一個類加載大概會向上委托兩次,兩次來讓父加載器加載,所以是雙親委派,當(dāng)然這也是個人猜測,網(wǎng)上查閱了很多資料,也是模棱兩可,其實(shí)大家也不必要對這種問題糾結(jié),聽聽就好

          雙親委派可以破壞嗎

          這個問題很經(jīng)典,面試如果問到JVM,這個問題大概率會被問到,這個時候就到了你裝*的時候了,這個時候就輪到給面試官好感,以及漲工資的時刻

          回答問題,一定要循序漸進(jìn),按照條理思路來分析,這樣會大大增加你在面試官心中的好感,別問我怎么知道的

          當(dāng)然可以破壞了,我們知道類的加載方式默認(rèn)是雙親委派,如果我們有一個類想要通過自定義的類加載器來加載這個類,而不是通過系統(tǒng)默認(rèn)的類加載器,說白了就是不走雙親委派那一套,而是走自定義的類加載器

          我們知道雙親委派的機(jī)制是ClassLoader中的loadClass方法實(shí)現(xiàn)的,打破雙親委派,其實(shí)就是重寫這個方法,來用我們自己的方式來實(shí)現(xiàn)即可

          當(dāng)然這里要注意一下,Object.class這是對象的頂級類,改變類的類加載器的時候要注意,如果全部改了,Object.class就找不到了,加載不了了

          所以呢,這里重寫的時候,要注意分類解決,把你想要通過自定義類加載器加載的和想通過默認(rèn)類加載器加載的分隔開


           


          求贊



           

          好了,以上就是全部內(nèi)容了,我是小魚仙,你們的學(xué)習(xí)成長小伙伴

                                       

          我希望有一天能夠靠寫字養(yǎng)活自己,現(xiàn)在還在磨練,這個時間可能會有很多年,感謝你們做我最初的讀者和傳播者。請大家相信,只要給我一份愛,我終究會還你們一頁情的。

          再次感謝大家能夠讀到這里,我后面會持續(xù)的更新技術(shù)文章以及一些記錄生活的靈魂文章,如果覺得不錯的,覺得大魚同學(xué)有點(diǎn)東西的話,求點(diǎn)贊、關(guān)注、分享三連

          哦,對了!后續(xù)的更新文章我都會及時放到這里,歡迎大家點(diǎn)擊觀看,都是干貨文章啊,建議收藏,以后隨時翻閱查看

          https://github.com/DayuMM2021/Java

           

          推薦閱讀


          ● 面試官問我:你確定用了BigDecimal后,計(jì)算結(jié)果一定精確?

             ● 這個GitHub地址,真香

          ● 消息隊(duì)列入門

             ● 搞懂什么是RocketMQ


          瀏覽 71
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  欧美综合激情网 | 黄网免费 | 久久黄色网片老女人做爱 | 成人网站在线看。 | www.久久精品视频 |