類加載

類的生命周期

類加載時機

虛擬機規(guī)范中沒有規(guī)定類加載的時機,但是規(guī)定了需要進行初始化的5種情況(而加載上陕、驗證桩砰、準備必須在此之前)。

  1. 遇到new释簿、getstatic亚隅、putstatic、invokestatic這四條字節(jié)碼指令時庶溶,也就是new一個對象或者讀寫一個類的字段或者調用一個類的方法煮纵。
  2. 通過反射調用一個類的時候。
  3. 初始化一個類是偏螺,如果父類還沒有初始化醉途,那么先初始化父類。
  4. 虛擬機啟動時砖茸,指定的含main()的主類隘擎。
  5. JDK1.7的動態(tài)語言支持,MethodHandle是一個類字段或者方法的句柄凉夯,如果這個類沒有初始化货葬,那么初始化。

不會初始化的情況:

  1. 子類引用父類的靜態(tài)字段和方法劲够,子類不會初始化震桶。
  2. 通過數組定義引用類,類不會初始化征绎。
  3. 引用可以在編譯期確定的常量類字段蹲姐,不會引起類初始化,因為這個常量已經被使用的類放入自身的常量池人柿。
  4. 一個接口初始化時不要求父接口完成初始化柴墩,只有在真正使用父接口時才需要初始化。

類加載的過程

指生命周期中的加載凫岖、驗證江咳、準備、解析和初始化

加載

  1. 虛擬機根據類的全限定名獲取類的二進制字節(jié)流哥放。
  2. 將字節(jié)流代表的靜態(tài)存儲結構轉化為方法區(qū)的運行時數據結構歼指。
  3. 內存中生成一個java.lang.Class對象爹土,作為方法區(qū)這個類的數據的入口。
獲炔壬怼:
  1. ZIP(jar, war, ear...)
  2. 網絡(applet)
  3. 運行時生成胀茵,Proxy動態(tài)代理
  4. 其他文件生成,JSP文件生成
  5. 數據庫

加載類的階段可以通過自定義類加載器來自定義挟阻,通過重寫loadClass()方法來控制獲取字節(jié)流宰掉。
但是數組類稍有特殊,例如數組類C:
(1)如果組件類型為引用類型赁濒,那么遞歸地加載這個組件類型轨奄,然后數組C將在加載了該組件類型的類加載器的類命名空間上被標識。
(2)如果組件類型不是引用類型拒炎,那么數組C會被標記為與引導類加載器關聯
(3)數組類的可見性和組件類型一致

存儲:

(1)二進制流以虛擬機所需格式存儲在方法區(qū)挪拟,格式由虛擬機實現自定。
(2)實例化一個java.lang.Class類的對象击你,HotSpot將這個對象放在了方法區(qū)玉组。

驗證

驗證字節(jié)流的信息符合虛擬機要求,并且不會危害虛擬機的安全丁侄。
字節(jié)碼層面來說惯雳,字節(jié)碼可以完成很多Java語言無法完成的操作,而字節(jié)碼可以使用很多方式生成鸿摇,不一定由Java源碼編譯而來石景,所以虛擬機為了保證自身安全,需要進行驗證拙吉。

  1. 文件格式驗證
  • 魔數
  • 主次版本號是否支持
  • 常量池中的常量類型
  • 指向常量的索引值指向是否有問題
  • 常量池UTF8類型常量的UTF8編碼
  • Class文件是否有被刪除或者附加的其他信息
    ......
    這一階段的驗證是基于字節(jié)流的潮孽,通過后,字節(jié)流才會進入方法區(qū)筷黔,后面的驗證會基于方法區(qū)內的存儲結構往史,而不再操作字節(jié)流。
  1. 元數據驗證
    進行語義分析佛舱,以保證滿足Java語言規(guī)范
  • 除了Object外應該有父類
  • 是否繼承了final類
  • 如果不是抽象類椎例,是否實現了所有需要實現的方法。
  • 字段與方法是否與父類矛盾(覆蓋了父類final字段请祖,不符合規(guī)則的重載)
    ......
  1. 字節(jié)碼驗證
    通過數據流與控制流分析订歪,確定程序語義是合法符合邏輯的。
  • 保證操作數棧的數據類型與字節(jié)碼指令能配合
  • 跳轉指令不會跳轉到方法體之外的字節(jié)碼指令
  • 類型轉換是有效的
    ......
    方法體的Code屬性的屬性表中在JDK1.6后添加了StackMapTable损拢,用于描述方法的所有基本塊開始時本地變量表和操作棧應有的狀態(tài)陌粹,驗證期間,不需要在根據程序推導這些狀態(tài)的合法性福压,只需要檢查StackMapTable屬性中的記錄是否合法即可掏秩,這樣將類型推導轉變?yōu)轭愋蜋z查。
  1. 符號引用驗證
    這個驗證發(fā)生在解析階段虛擬機將符號引用轉化為直接引用的時候荆姆,對類自身以外的信息進行匹配性校驗:
  • 字符串描述的全限定名能否找到對應的類
  • 指定類中是否存在符合方法描述符所描述的方法蒙幻,是否存在簡單名稱所描述的字段
  • 符號引用中的類、字段胆筒、方法的訪問性是否可被當前類訪問

準備

為類變量在方法區(qū)中分配內存邮破,并設零值(零值而非初始值),賦初始值的指令在<clinit>()方法中仆救,在初始化階段執(zhí)行抒和。
但如果是final變量,字段屬性表中包括ConstantValue的屬性彤蔽,那么會設為ConstantValue的值摧莽。

解析

將常量池中的符號引用替換為直接引用,包括常量池中的CONSTANT_Class_info顿痪、CONSTANT_Fieldref_info镊辕、CONSTANT_Methodref_info等
詳見《深入理解虛擬機》P221

初始化

執(zhí)行<clinit>()方法

  • <clinit>()方法內容來自于類變量的復制動作和static塊,按聲明順序
  • <clinit>()方法與構造函數不同蚁袭,不需要顯示調用父類構造器征懈,虛擬機保證父類的<clinit>()方法已經執(zhí)行
  • <clinit>()不是必須的
  • 接口沒有初始化塊,但是可以有賦值
  • 虛擬機保證一個類的<clinit>()方法在多線程環(huán)境下能被正確地加鎖同步揩悄,如果多線程同時去初始化一個類卖哎,那么只有一個線程會執(zhí)行類的<clinit>()方法,其他線程會阻塞删性。同一個類加載器下棉饶,一個類只會初始化一次。

類加載器

主要是加載階段的“通過一個類的全限定名獲取此類的二進制字節(jié)流”
用于類層次劃分镇匀,OSGi照藻,熱部署,代碼加密等領域

類與類加載器

任意一個類都要由加載它的類加載器和類本身一同確立它在Java虛擬機中的唯一性汗侵,也就是每個類加載器都有自己獨立的類名稱空間幸缕。

雙親委派模型
  • 啟動類加載器(Bootstrap ClassLoader):
    <JAVA_HOME>\lib和-Xbootclasspath
  • 擴展類加載器(Extension ClassLoader):
    <JAVA_HOME>\lib\ext或者java.ext.dirs系統(tǒng)變量指定的類庫
  • 應用程序加載器(Application ClassLoader):
    ClassPath
  • 自定義類加載器:
    父類加載器為應用程序加載器,通過組合實現

好處:
Java類隨著類加載器有了層級關系

摘抄自《深入理解Java虛擬機》

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末晰韵,一起剝皮案震驚了整個濱河市发乔,隨后出現的幾起案子,更是在濱河造成了極大的恐慌雪猪,老刑警劉巖栏尚,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異只恨,居然都是意外死亡译仗,警方通過查閱死者的電腦和手機抬虽,發(fā)現死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來纵菌,“玉大人阐污,你說我怎么就攤上這事≡墼玻” “怎么了笛辟?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長序苏。 經常有香客問我手幢,道長,這世上最難降的妖魔是什么忱详? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任围来,我火速辦了婚禮,結果婚禮上踱阿,老公的妹妹穿的比我還像新娘管钳。我一直安慰自己,他們只是感情好软舌,可當我...
    茶點故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布才漆。 她就那樣靜靜地躺著,像睡著了一般佛点。 火紅的嫁衣襯著肌膚如雪醇滥。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天超营,我揣著相機與錄音鸳玩,去河邊找鬼。 笑死演闭,一個胖子當著我的面吹牛不跟,可吹牛的內容都是我干的。 我是一名探鬼主播米碰,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼窝革,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了吕座?” 一聲冷哼從身側響起虐译,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎吴趴,沒想到半個月后漆诽,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年厢拭,在試婚紗的時候發(fā)現自己被綠了兰英。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡蚪腐,死狀恐怖箭昵,靈堂內的尸體忽然破棺而出税朴,到底是詐尸還是另有隱情回季,我是刑警寧澤,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布正林,位于F島的核電站泡一,受9級特大地震影響,放射性物質發(fā)生泄漏觅廓。R本人自食惡果不足惜鼻忠,卻給世界環(huán)境...
    茶點故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望杈绸。 院中可真熱鬧帖蔓,春花似錦、人聲如沸瞳脓。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽劫侧。三九已至埋酬,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間烧栋,已是汗流浹背写妥。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留审姓,地道東北人珍特。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像魔吐,于是被迫代替她去往敵國和親扎筒。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,843評論 2 354

推薦閱讀更多精彩內容