Android熱更新一:JAVA的類加載機制

很早之前就想深入的研究和學習一下熱修復狭吼,由于時間的原因一直拖著稠通,現(xiàn)在才執(zhí)筆弄起來衬衬。


Android而更新系列:
Android熱更新一:JAVA的類加載機制
Android熱更新二:理解Java反射
Android熱更新三:Android類加載機制
Android熱更新四:熱修復機制
Android熱更新五:四大熱修復方案分析
Android熱更新六:Qzone熱更新原理
Android熱更新七:Tinker熱更新原理
Android熱更新八:AndFix熱更新原理
Android熱更新九:Robust熱更新原理
Android熱更新十:自己寫一個Android熱修復


既然本次主題是熱修復买猖,在深入研究之前,要先搞清楚它涉及到的關(guān)鍵技術(shù)

類加載機制
Java反射

正所謂磨刀不誤砍柴工滋尉,我們這個筆記將對JAVA類加載機制進行初步學習和理解玉控。

一. 類加載機制

我們先了解類在JVM(Java虛擬機)中是如何加載的,這對后面理解java其它機制將有重要作用狮惜。

每個類編譯后產(chǎn)生一個Class對象奸远,存儲在.class文件中,JVM使用類加載器(Class Loader)來加載類的字節(jié)碼文件(.class)讽挟,類加載器實質(zhì)上是一條類加載器鏈懒叛,一般的,我們只會用到一個原生的類加載器耽梅,它只加載Java API等可信類薛窥,通常只是在本地磁盤中加載,這些類一般就夠我們使用了眼姐。如果我們需要從遠程網(wǎng)絡(luò)或數(shù)據(jù)庫中下載.class字節(jié)碼文件诅迷,那就需要我們來掛載額外的類加載器。

一般來說众旗,類加載器是按照樹形的層次結(jié)構(gòu)組織的罢杉,每個加載器都有一個父類加載器。另外贡歧,每個類加載器都支持代理模式滩租,即可以自己完成Java類的加載工作,也可以代理給其它類加載器利朵。

類加載器的加載順序有兩種:

  • 父類優(yōu)先策略是比較一般的情況(如JDK采用的就是這種方式)律想,在這種策略下,類在加載某個Java類之前绍弟,會嘗試代理給其父類加載器技即,只有當父類加載器找不到時,才嘗試自己去加載樟遣。
  • 自己優(yōu)先的策略與父類優(yōu)先相反而叼,它會首先嘗試子自己加載,找不到的時候才要父類加載器去加載豹悬,這種在web容器(如tomcat)中比較常見葵陵。

二. 類的加載和初始化

需要區(qū)分加載和初始化的區(qū)別,加載了一個類的.class文件屿衅,不意味著該Class對象被初始化埃难,事實上,一個類的初始化包括3個步驟:

  1. 加載(Loading),由類加載器執(zhí)行涡尘,查找字節(jié)碼忍弛,并創(chuàng)建一個Class對象(只是創(chuàng)建);
  2. 鏈接(Linking)考抄,驗證字節(jié)碼细疚,為靜態(tài)域分配存儲空間(只是分配,并不初始化該存儲空間)川梅,解析該類創(chuàng)建所需要的對其它類的應用疯兼;
  3. 初始化(Initialization),首先執(zhí)行靜態(tài)初始化塊static{}贫途,初始化靜態(tài)變量吧彪,執(zhí)行靜態(tài)方法(如構(gòu)造方法)。

1. 動態(tài)加載

不管使用什么樣的類加載器丢早,類姨裸,都是在第一次被用到時,動態(tài)加載到JVM的怨酝。這句話有兩層含義:

    1. Java程序在運行時并不一定被完整加載傀缩,只有當發(fā)現(xiàn)該類還沒有加載時,才去本地或遠程查找類的.class文件并驗證和加載农猬;
    1. 當程序創(chuàng)建了第一個對類的靜態(tài)成員的引用(如類的靜態(tài)變量赡艰、靜態(tài)方法、構(gòu)造方法——構(gòu)造方法也是靜態(tài)的)時斤葱,才會加載該類慷垮。Java的這個特性叫做:動態(tài)加載

2. 鏈接

Java在加載了類之后苦掘,需要進行鏈接的步驟换帜,鏈接簡單地說,就是將已經(jīng)加載的java二進制代碼組合到JVM運行狀態(tài)中去鹤啡。它包括3個步驟:

  1. 驗證(Verification),驗證是保證二進制字節(jié)碼在結(jié)構(gòu)上的正確性蹲嚣,具體來說递瑰,工作包括檢測類型正確性,接入屬性正確性(public隙畜、private)抖部,檢查final class 沒有被繼承,檢查靜態(tài)變量的正確性等议惰。
  2. 準備(Preparation)慎颗,準備階段主要是創(chuàng)建靜態(tài)域,分配空間,給這些域設(shè)默認值俯萎,需要注意的是兩點:一個是在準備階段不會執(zhí)行任何代碼傲宜,僅僅是設(shè)置默認值,二個是這些默認值是這樣分配的夫啊,原生類型全部設(shè)為0函卒,如:float:0f,int 0, long 0L, boolean:0(布爾類型也是0),其它引用類型為null撇眯。
  3. 解析(Resolution)报嵌,解析的過程就是對類中的接口、類熊榛、方法锚国、變量的符號引用進行解析并定位,解析成直接引用(符號引用就是編碼是用字符串表示某個變量玄坦、接口的位置血筑,直接引用就是根據(jù)符號引用翻譯出來的地址),并保證這些類被正確的找到营搅。解析的過程可能導致其它的類被加載云挟。需要注意的是,根據(jù)不同的解析策略转质,這一步不一定是必須的园欣,有些解析策略在解析時遞歸的把所有引用解析,這是early resolution休蟹,要求所有引用都必須存在沸枯;還有一種策略是late resolution,這也是Oracle 的JDK所采取的策略赂弓,即在類只是被引用了绑榴,還沒有被真正用到時,并不進行解析盈魁,只有當真正用到了翔怎,才去加載和解析這個類。

3. 初始化

根據(jù)java虛擬機規(guī)范杨耙,所有java虛擬機實現(xiàn)必須在每個類或接口被java程序首次主動使用時才初始化赤套。

主動使用有以下6種:

  1. 創(chuàng)建類的實例
  2. 訪問某個類或者接口的靜態(tài)變量,或者對該靜態(tài)變量賦值(如果訪問靜態(tài)編譯時常量(即編譯時可以確定值的常量)不會導致類的初始化)
  3. 調(diào)用類的靜態(tài)方法
  4. 反射(Class.forName(xxx.xxx.xxx))
  5. 初始化一個類的子類(相當于對父類的主動使用)珊膜,不過直接通過子類引用父類元素容握,不會引起子類的初始化
  6. Java虛擬機被標明為啟動類的類(包含main方法的)

類與接口的初始化不同,如果一個類被初始化车柠,則其父類或父接口也會被初始化剔氏,但如果一個接口初始化塑猖,則不會引起其父接口的初始化。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末谈跛,一起剝皮案震驚了整個濱河市羊苟,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌币旧,老刑警劉巖践险,帶你破解...
    沈念sama閱讀 216,651評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異吹菱,居然都是意外死亡巍虫,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評論 3 392
  • 文/潘曉璐 我一進店門鳍刷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來占遥,“玉大人,你說我怎么就攤上這事输瓜⊥咛ィ” “怎么了?”我有些...
    開封第一講書人閱讀 162,931評論 0 353
  • 文/不壞的土叔 我叫張陵尤揣,是天一觀的道長搔啊。 經(jīng)常有香客問我,道長北戏,這世上最難降的妖魔是什么负芋? 我笑而不...
    開封第一講書人閱讀 58,218評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮嗜愈,結(jié)果婚禮上旧蛾,老公的妹妹穿的比我還像新娘。我一直安慰自己蠕嫁,他們只是感情好锨天,可當我...
    茶點故事閱讀 67,234評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著剃毒,像睡著了一般病袄。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上赘阀,一...
    開封第一講書人閱讀 51,198評論 1 299
  • 那天陪拘,我揣著相機與錄音,去河邊找鬼纤壁。 笑死,一個胖子當著我的面吹牛捺信,可吹牛的內(nèi)容都是我干的酌媒。 我是一名探鬼主播欠痴,決...
    沈念sama閱讀 40,084評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼秒咨!你這毒婦竟也來了喇辽?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,926評論 0 274
  • 序言:老撾萬榮一對情侶失蹤雨席,失蹤者是張志新(化名)和其女友劉穎菩咨,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體陡厘,經(jīng)...
    沈念sama閱讀 45,341評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡抽米,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,563評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了糙置。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片云茸。...
    茶點故事閱讀 39,731評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖谤饭,靈堂內(nèi)的尸體忽然破棺而出标捺,到底是詐尸還是另有隱情,我是刑警寧澤揉抵,帶...
    沈念sama閱讀 35,430評論 5 343
  • 正文 年R本政府宣布亡容,位于F島的核電站,受9級特大地震影響冤今,放射性物質(zhì)發(fā)生泄漏闺兢。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,036評論 3 326
  • 文/蒙蒙 一辟汰、第九天 我趴在偏房一處隱蔽的房頂上張望列敲。 院中可真熱鬧,春花似錦帖汞、人聲如沸戴而。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽所意。三九已至,卻和暖如春催首,著一層夾襖步出監(jiān)牢的瞬間扶踊,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評論 1 269
  • 我被黑心中介騙來泰國打工郎任, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留秧耗,地道東北人。 一個月前我還...
    沈念sama閱讀 47,743評論 2 368
  • 正文 我出身青樓舶治,卻偏偏與公主長得像分井,于是被迫代替她去往敵國和親车猬。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,629評論 2 354

推薦閱讀更多精彩內(nèi)容