JVM實(shí)戰(zhàn)---類加載的過程

任何程序都需要加載到內(nèi)存才能與CPU進(jìn)行交流
同理, 字節(jié)碼.class文件同樣需要加載到內(nèi)存中章郁,才可以實(shí)例化類
ClassLoader的使命就是提前加載.class 類文件到內(nèi)存中
在加載類時(shí),使用的是Parents Delegation Model(溯源委派加載模型)

Java的類加載器是一個(gè)運(yùn)行時(shí)核心基礎(chǔ)設(shè)施模塊示损,主要是在啟動之初進(jìn)行類的加載寿弱、鏈接犯眠、初始化


Java 類加載過程

第一步,Load階段

讀取類文件產(chǎn)生二進(jìn)制流症革,并轉(zhuǎn)為特定數(shù)據(jù)結(jié)構(gòu)筐咧,初步校驗(yàn)cafe babe魔法數(shù)、常量池、文件長度量蕊、是否有父類等铺罢,然后創(chuàng)建對應(yīng)類的java.lang.Class實(shí)例

第二步,Link階段

包括驗(yàn)證残炮、準(zhǔn)備韭赘、解析三個(gè)步驟

  • 驗(yàn)證是更詳細(xì)的校驗(yàn),比如final是否合規(guī)势就、類型是否正確泉瞻、靜態(tài)變量是否合理等
  • 準(zhǔn)備階段是為靜態(tài)變量分配內(nèi)存,并設(shè)定默認(rèn)值苞冯,解析類和方法確保類與類之間的相互引用正確性袖牙,完成內(nèi)存結(jié)構(gòu)布局

第三步,Init 階段

執(zhí)行類構(gòu)造器<clinit> 方法舅锄,如果賦值運(yùn)算是通過其他類的靜態(tài)方法來完成的鞭达,那么會馬上解析另外一個(gè)類,在虛擬機(jī)棧中執(zhí)行完畢后通過返回值進(jìn)行賦值

類加載是一個(gè)將.class字節(jié)碼文件實(shí)例化成Class對象并進(jìn)行相關(guān)初始化的過程皇忿。
在這個(gè)過程中畴蹭,JVM會初始化繼承樹上還沒有被初始化過的所有父類,并且會執(zhí)行這個(gè)鏈路上所有未執(zhí)行過的靜態(tài)代碼塊禁添、靜態(tài)變量賦值語句等撮胧。
某些類在使用時(shí)桨踪,也可以按需由類加載器進(jìn)行加載老翘。

全小寫的class是關(guān)鍵字,用來定義類
而首字母大寫的Class,它是所有class的類
這句話理解起來有難度锻离,類已經(jīng)是現(xiàn)實(shí)世界中某種事物的抽象铺峭,為什么這個(gè)抽象還是另外一個(gè)類Class的對象?
示例代碼如下:





● 第1處說明:
Class類下的newInstance()在JDK9中已經(jīng)置為過時(shí),使用getDeclaredConstructor().newInstance()的方式
著重說明一下new與newInstance的區(qū)別

  • new是強(qiáng)類型校驗(yàn)汽纠,可以調(diào)用任何構(gòu)造方法卫键,在使用new操作的時(shí)候,這個(gè)類可以沒有被加載過
  • 而Class類下的newInstance是弱類型虱朵,只能調(diào)用無參構(gòu)造方法
    • 如果沒有默認(rèn)構(gòu)造方法莉炉,就拋出InstantiationException異常;
    • 如果此構(gòu)造方法沒有權(quán)限訪問,則拋 IllegalAccessException異常

Java 通過類加載器把類的實(shí)現(xiàn)與類的定義進(jìn)行解耦碴犬,所以是實(shí)現(xiàn)面向接口編程絮宁、依賴倒置的必然選擇。

● 第2處說明:
可以使用類似的方式獲取其他聲明服协,如注解绍昂、方法等


類的反射信息

● 第3處說明: private 成員在類外是否可以修改?
通過setccessible(true),即可使用Class類的set方法修改其值
如果沒有這一步,則拋出如下異常:

類加載器

類加載器是如何定位具體的類文件并讀取的呢?

在類加載器家族中存在著類似人類社會的權(quán)力等級制度

  • 最高層的Bootstrap
    在JVM啟動時(shí)創(chuàng)建的,通常由與操作系統(tǒng)相關(guān)的本地代碼實(shí)現(xiàn),是最根基的類加載器,負(fù)責(zé)裝載最核心的Java類,比如Object、System、 String ,Java運(yùn)行時(shí)的rt.jar等jar包
  • JDK9的Platform ClassLoader
    負(fù)責(zé)加載<JAVA_HOME>\lib\ext目錄中的窘游,或者java.ext.dirs系統(tǒng)變量指定的路徑中的所以類庫;
    加載一些擴(kuò)展的系統(tǒng)類唠椭,比如XML、加密忍饰、壓縮相關(guān)的功能類等;
    JDK9之前是Extension ClassLoader.
  • 第三層 Application ClassLoader
    應(yīng)用類加載器贪嫂,主要是加載用戶定義的CLASSPATH路徑下的類

第二、三層類加載器為Java語言實(shí)現(xiàn)艾蓝,用戶也可以自定義類加載器
查看本地類加載器的方式如下:



在JDK8環(huán)境中撩荣,執(zhí)行結(jié)果如下



AppClassLoader的Parent為Bootstrap,它是通過C/C++實(shí)現(xiàn)的,并不存在于JVM體系內(nèi),所以輸出為 null

低層次的當(dāng)前類加載器饶深,不能覆蓋更高層次類加載器已經(jīng)加載的類

如果低層次的類加載器想加載一個(gè)未知類餐曹,要非常禮貌地向上逐級詢問:“請問,這個(gè)類已經(jīng)加載了嗎?”
被詢問的高層次類加載器會自問兩個(gè)問題

  • 我是否已加載過此類
  • 如果沒有敌厘,是否可以加載此類

只有當(dāng)所有高層次類加載器在兩個(gè)問題的答案均為“否”時(shí)台猴,才可以讓當(dāng)前類加載器加載這個(gè)未知類
左側(cè)綠色箭頭向上逐級詢問是否已加載此類,直至Bootstrap ClassLoader,然后向下逐級嘗試是否能夠加載此類俱两,如果都加載不了饱狂,則通知發(fā)起加載請求的當(dāng)前類加載器,準(zhǔn)予加載
在右側(cè)的三個(gè)小標(biāo)簽里宪彩,列舉了此層類加載器主要加載的代表性類庫休讳,事實(shí)上不止于此

通過如下代碼可以查看Bootstrap 所有已加載類庫



執(zhí)行結(jié)果


Bootstrap加載的路徑可以追加,不建議修改或刪除原有加載路徑
在JVM中增加如下啟動參數(shù)尿孔,則能通過Class.forName正常讀取到指定類俊柔,說明此參數(shù)可以增加Bootstrap的類加載路徑:

-Xbootclasspath/a:/Users/sss/book/ easyCoding/byJdk11/src

如果想在啟動時(shí)觀察加載了哪個(gè)jar包中的哪個(gè)類,可以增加

-XX:+TraceClassLoading

此參數(shù)在解決類沖突時(shí)非常實(shí)用活合,畢竟不同的JVM環(huán)境對于加載類的順序并非是一致的
有時(shí)想觀察特定類的加載上下文雏婶,由于加載的類數(shù)量眾多,調(diào)試時(shí)很難捕捉到指定類的加載過程白指,這時(shí)可以使用條件斷點(diǎn)功能
比如留晚,想查看HashMap的加載過程,在loadClass處打個(gè)斷點(diǎn)告嘲,并且在condition框內(nèi)輸入如圖


設(shè)置條件斷點(diǎn)

JVM如何確立每個(gè)類在JVM的唯一性

類的全限定名和加載這個(gè)類的類加載器的ID

在學(xué)習(xí)了類加載器的實(shí)現(xiàn)機(jī)制后错维,知道雙親委派模型并非強(qiáng)制模型,用戶可以自定義類加載器橄唬,在什么情況下需要自定義類加載器呢?

  • 隔離加載類
    在某些框架內(nèi)進(jìn)行中間件與應(yīng)用的模塊隔離赋焕,把類加載到不同的環(huán)境
    比如,阿里內(nèi)某容器框架通過自定義類加載器確保應(yīng)用中依賴的jar包不會影響到中間件運(yùn)行時(shí)使用的jar包
  • 修改類加載方式
    類的加載模型并非強(qiáng)制轧坎,除Bootstrap外宏邮,其他的加載并非一定要引入,或者根據(jù)實(shí)際情況在某個(gè)時(shí)間點(diǎn)進(jìn)行按需進(jìn)行動態(tài)加載
  • 擴(kuò)展加載源
    比如從數(shù)據(jù)庫、網(wǎng)絡(luò)蜜氨,甚至是電視機(jī)機(jī)頂盒進(jìn)行加載
  • 防止源碼泄露
    Java代碼容易被編譯和篡改械筛,可以進(jìn)行編譯加密。那么類加載器也需要自定義飒炎,還原加密的字節(jié)碼埋哟。

實(shí)現(xiàn)自定義類加載器的步驟

  • 繼承ClassLoader
  • 重寫findClass()方法
  • 調(diào)用defineClass()方法

一個(gè)簡單的類加載器實(shí)現(xiàn)的示例代碼如下


由于中間件一般都有自己的依賴jar包,在同一個(gè)工程內(nèi)引用多個(gè)框架時(shí)郎汪,往往被迫進(jìn)行類的仲裁
按某種規(guī)則jar包的版本被統(tǒng)一指定赤赊, 導(dǎo)致某些類存在包路徑、類名相同的情況煞赢,就會引起類沖突抛计,導(dǎo)致應(yīng)用程序出現(xiàn)異常
主流的容器類框架都會自定義類加載器,實(shí)現(xiàn)不同中間件之間的類隔離照筑,有效避免了類沖突吹截。

1 加載的定位

“加載”是“類加載”(Class Loading)過程的第一步

1.1 加載的過程

在加載的過程中,JVM主要做3件事情

  • 通過一個(gè)類的全限定名來獲取定義此類的二進(jìn)制字節(jié)流(class文件)
    在程序運(yùn)行過程中,當(dāng)要訪問一個(gè)類時(shí),若發(fā)現(xiàn)這個(gè)類尚未被加載,并滿足類初始化的條件時(shí),就根據(jù)要被初始化的這個(gè)類的全限定名找到該類的二進(jìn)制字節(jié)流,開始加載過程
  • 將這個(gè)字節(jié)流的靜態(tài)存儲結(jié)構(gòu)轉(zhuǎn)化為方法區(qū)的運(yùn)行時(shí)數(shù)據(jù)結(jié)構(gòu)
  • 在內(nèi)存中創(chuàng)建一個(gè)該類的java.lang.Class對象,作為方法區(qū)該類的各種數(shù)據(jù)的訪問入口

程序在運(yùn)行中所有對該類的訪問都通過這個(gè)類對象,也就是這個(gè)Class對象是提供給外界訪問該類的接口

1.2 加載源

JVM規(guī)范對于加載過程給予了較大的寬松度.一般二進(jìn)制字節(jié)流都從已經(jīng)編譯好的本地class文件中讀取,此外還可以從以下地方讀取

  • zip包
    Jar凝危、War波俄、Ear等
  • 其它文件生成
    由JSP文件中生成對應(yīng)的Class類.
  • 數(shù)據(jù)庫中
    將二進(jìn)制字節(jié)流存儲至數(shù)據(jù)庫中,然后在加載時(shí)從數(shù)據(jù)庫中讀取.有些中間件會這么做,用來實(shí)現(xiàn)代碼在集群間分發(fā)
  • 網(wǎng)絡(luò)
    從網(wǎng)絡(luò)中獲取二進(jìn)制字節(jié)流.典型就是Applet.
  • 運(yùn)行時(shí)計(jì)算生成
    動態(tài)代理技術(shù),用PRoxyGenerator.generateProxyClass為特定接口生成形式為"*$Proxy"的代理類的二進(jìn)制字節(jié)流.

1.3 類和數(shù)組加載過程的區(qū)別

數(shù)組也有類型,稱為“數(shù)組類型”.如:

String[] str = new String[10];

這個(gè)數(shù)組的數(shù)組類型是Ljava.lang.String,而String只是這個(gè)數(shù)組的元素類型

當(dāng)程序在運(yùn)行過程中遇到new關(guān)鍵字創(chuàng)建一個(gè)數(shù)組時(shí),由JVM直接創(chuàng)建數(shù)組類,再由類加載器創(chuàng)建數(shù)組中的元素類型.

而普通類的加載由類加載器創(chuàng)建.既可以使用系統(tǒng)提供的引導(dǎo)類加載器,也可以由用戶自定義的類加載器完成(即重寫一個(gè)類加載器的loadClass()方法)

1.4 加載過程的注意點(diǎn)

  • JVM規(guī)范并未給出類在方法區(qū)中存放的數(shù)據(jù)結(jié)構(gòu)
    類完成加載后,二進(jìn)制字節(jié)流就以特定的數(shù)據(jù)結(jié)構(gòu)存儲在方法區(qū)中,但存儲的數(shù)據(jù)結(jié)構(gòu)是由虛擬機(jī)自己定義的,虛擬機(jī)規(guī)范并沒有指定
  • JVM規(guī)范并沒有指定Class對象存放的位置
    在二進(jìn)制字節(jié)流以特定格式存儲在方法區(qū)后,JVM會創(chuàng)建一個(gè)java.lang.Class類的對象,作為本類的外部訪問接口
    既然是對象就應(yīng)該存放在Java堆中,不過JVM規(guī)范并沒有給出限制,不同的虛擬機(jī)根據(jù)自己的需求存放這個(gè)對象
    HotSpot將Class對象存放在方法區(qū).
  • 加載階段和鏈接階段是交叉的
    類加載的過程中每個(gè)步驟的開始順序都有嚴(yán)格限制,但每個(gè)步驟的結(jié)束順序沒有限制.也就是說,類加載過程中,必須按照如下順序開始:

加載 -> 鏈接 -> 初始化

但結(jié)束順序無所謂,因此由于每個(gè)步驟處理時(shí)間的長短不一就會導(dǎo)致有些步驟會出現(xiàn)交叉

2 驗(yàn)證

驗(yàn)證階段比較耗時(shí),它非常重要但不一定必要(因?yàn)閷Τ绦蜻\(yùn)行期沒有影響),如果所運(yùn)行的代碼已經(jīng)被反復(fù)使用和驗(yàn)證過,那么可以使用-Xverify:none參數(shù)關(guān)閉,以縮短類加載時(shí)間

2.1 驗(yàn)證的目的

保證二進(jìn)制字節(jié)流中的信息符合虛擬機(jī)規(guī)范,并沒有安全問題

2.2 驗(yàn)證的必要性

雖然Java語言是一門安全的語言,它能確保程序猿無法訪問數(shù)組邊界以外的內(nèi)存、避免讓一個(gè)對象轉(zhuǎn)換成任意類型蛾默、避免跳轉(zhuǎn)到不存在的代碼行.也就是說,Java語言的安全性是通過編譯器來保證的.

但是我們知道,編譯器和虛擬機(jī)是兩個(gè)獨(dú)立的東西,虛擬機(jī)只認(rèn)二進(jìn)制字節(jié)流,它不會管所獲得的二進(jìn)制字節(jié)流是哪來的懦铺,當(dāng)然,如果是編譯器給它的支鸡,那么就相對安全冬念,但如果是從其它途徑獲得的,那么無法確保該二進(jìn)制字節(jié)流是安全的苍匆。

通過上文可知刘急,虛擬機(jī)規(guī)范中沒有限制二進(jìn)制字節(jié)流的來源棚菊,在字節(jié)碼層面上,上述Java代碼無法做到的都是可以實(shí)現(xiàn)的,至少語義上是可以表達(dá)出來的,為了防止字節(jié)流中有安全問題浸踩,需要驗(yàn)證!

2.3 驗(yàn)證的過程

  • 文件格式驗(yàn)證
    驗(yàn)證字節(jié)流是否符合Class文件格式的規(guī)范,并且能被當(dāng)前的虛擬機(jī)處理.
    本驗(yàn)證階段是基于二進(jìn)制字節(jié)流進(jìn)行的,只有通過本階段驗(yàn)證,才被允許存到方法區(qū)
    后面的三個(gè)驗(yàn)證階段都是基于方法區(qū)的存儲結(jié)構(gòu)進(jìn)行,不會再直接操作字節(jié)流.

通過上文可知统求,加載開始前检碗,二進(jìn)制字節(jié)流還沒進(jìn)方法區(qū),而加載完成后码邻,二進(jìn)制字節(jié)流已經(jīng)存入方法區(qū)
而在文件格式驗(yàn)證前折剃,二進(jìn)制字節(jié)流尚未進(jìn)入方法區(qū),文件格式驗(yàn)證通過之后才進(jìn)入方法區(qū)
也就是說像屋,加載開始后怕犁,立即啟動了文件格式驗(yàn)證,本階段驗(yàn)證通過后,二進(jìn)制字節(jié)流被轉(zhuǎn)換成特定數(shù)據(jù)結(jié)構(gòu)存儲至方法區(qū)中奏甫,繼而開始下階段的驗(yàn)證和創(chuàng)建Class對象等操作
這個(gè)過程印證了:加載和驗(yàn)證是交叉進(jìn)行的

  • 元數(shù)據(jù)驗(yàn)證
    對字節(jié)碼描述信息進(jìn)行語義分析,確保符合Java語法規(guī)范.
  • 字節(jié)碼驗(yàn)證
    本階段是驗(yàn)證過程的最復(fù)雜的一個(gè)階段.
    本階段對方法體進(jìn)行語義分析,保證方法在運(yùn)行時(shí)不會出現(xiàn)危害虛擬機(jī)的事件.
    字節(jié)碼驗(yàn)證將對類的方法進(jìn)行校驗(yàn)分析戈轿,保證被校驗(yàn)的方法在運(yùn)行時(shí)不會做出危害虛擬機(jī)的事,一個(gè)類方法體的字節(jié)碼沒有通過字節(jié)碼驗(yàn)證阵子,那一定有問題思杯,但若一個(gè)方法通過了驗(yàn)證,也不能說明它一定安全
  • 符號引用驗(yàn)證
    發(fā)生在JVM將符號引用轉(zhuǎn)化為直接引用的時(shí)候,這個(gè)轉(zhuǎn)化動作發(fā)生在解析階段,對類自身以外的信息進(jìn)行匹配校驗(yàn),確保解析能正常執(zhí)行.

3 準(zhǔn)備

完成兩件事情

  • 為已在方法區(qū)中的類的靜態(tài)成員變量分配內(nèi)存
  • 為靜態(tài)成員變量設(shè)置初始值
    初始值為0挠进、false色乾、null等


public static final int value = 123;

準(zhǔn)備階段后 a 的值為 0,而不是 123领突,要在初始化之后才變?yōu)?123,但若被final修飾的常量如果有初始值,那么在編譯階段就會將初始值存入constantValue屬性中,在準(zhǔn)備階段就將constantValue的值賦給該字段(此處將value賦為123).

4 解析

解析階段是虛擬機(jī)將常量池中的符號引用替換為直接引用的過程.

5 初始化

真正開始執(zhí)行類中定義的Java程序代碼(或者說是字節(jié)碼)
初始化階段就是執(zhí)行類構(gòu)造器clinit()的過程.

clinit()方法由編譯器自動產(chǎn)生暖璧,收集類中static{}代碼塊中的類變量賦值語句和類中靜態(tài)成員變量的賦值語句。在準(zhǔn)備階段君旦,類中靜態(tài)成員變量已經(jīng)完成了默認(rèn)初始化漆撞,而在初始化階段,clinit()方法對靜態(tài)成員變量進(jìn)行顯示初始化于宙。

5.1 初始化過程的注意點(diǎn)

  • clinit()方法是IDE自動收集類中所有類變量的賦值動作和靜態(tài)語句塊中的語句合并產(chǎn)生的,IDE收集的順序是由語句在源文件中出現(xiàn)的順序所決定的.
  • 靜態(tài)代碼塊只能訪問到出現(xiàn)在靜態(tài)代碼塊之前的變量,定義在它之后的變量,在前面的靜態(tài)語句塊可以賦值,但是不能訪問.
public class Test {
    static {
        i=0;
        System.out.println(i);//編譯失敗:"非法向前引用"
    }
    static int i = 1;
}
  • 實(shí)例構(gòu)造器init()需要顯示調(diào)用父類構(gòu)造函數(shù),而類的clinit()不需要調(diào)用父類的類構(gòu)造函數(shù),虛擬機(jī)會確保子類的clinit()方法執(zhí)行前已經(jīng)執(zhí)行完畢父類的clinit()方法.因此在JVM中第一個(gè)被執(zhí)行的clinit()方法的類肯定是java.lang.Object.
  • 如果一個(gè)類/接口中沒有靜態(tài)代碼塊,也沒有靜態(tài)成員變量的賦值操作,那么編譯器就不會為此類生成clinit()方法.
  • 接口也需要通過clinit()方法為接口中定義的靜態(tài)成員變量顯示初始化浮驳。
  • 接口中不能使用靜態(tài)代碼塊,但仍然有變量初始化的賦值操作,因此接口與類一樣都會生成clinit()方法.不同的是,執(zhí)行接口的clinit()方法不需要先執(zhí)行父接口的clinit()方法.只有當(dāng)父接口中的靜態(tài)成員變量被使用到時(shí)才會執(zhí)行父接口的clinit()方法.
  • 虛擬機(jī)會保證在多線程環(huán)境中一個(gè)類的clinit()方法別正確地加鎖,同步.當(dāng)多條線程同時(shí)去初始化一個(gè)類時(shí),只會有一個(gè)線程去執(zhí)行該類的clinit()方法,其它線程都被阻塞等待,直到活動線程執(zhí)行clinit()方法完畢.

其他線程雖會被阻塞,只要有一個(gè)clinit()方法執(zhí)行完,其它線程喚醒后不會再進(jìn)入clinit()方法.同一個(gè)類加載器下,一個(gè)類型只會初始化一次.

參考

  • 《碼到成功》

  • 《深入理解Java虛擬機(jī)第二版》

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末捞魁,一起剝皮案震驚了整個(gè)濱河市至会,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌谱俭,老刑警劉巖奉件,帶你破解...
    沈念sama閱讀 218,525評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異昆著,居然都是意外死亡县貌,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評論 3 395
  • 文/潘曉璐 我一進(jìn)店門凑懂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來煤痕,“玉大人,你說我怎么就攤上這事接谨“诘铮” “怎么了?”我有些...
    開封第一講書人閱讀 164,862評論 0 354
  • 文/不壞的土叔 我叫張陵脓豪,是天一觀的道長巷帝。 經(jīng)常有香客問我,道長扫夜,這世上最難降的妖魔是什么楞泼? 我笑而不...
    開封第一講書人閱讀 58,728評論 1 294
  • 正文 為了忘掉前任驰徊,我火速辦了婚禮,結(jié)果婚禮上堕阔,老公的妹妹穿的比我還像新娘辣垒。我一直安慰自己,他們只是感情好印蔬,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,743評論 6 392
  • 文/花漫 我一把揭開白布勋桶。 她就那樣靜靜地躺著,像睡著了一般侥猬。 火紅的嫁衣襯著肌膚如雪例驹。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,590評論 1 305
  • 那天退唠,我揣著相機(jī)與錄音鹃锈,去河邊找鬼。 笑死瞧预,一個(gè)胖子當(dāng)著我的面吹牛屎债,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播垢油,決...
    沈念sama閱讀 40,330評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼盆驹,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了滩愁?” 一聲冷哼從身側(cè)響起躯喇,我...
    開封第一講書人閱讀 39,244評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎硝枉,沒想到半個(gè)月后廉丽,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,693評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡妻味,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,885評論 3 336
  • 正文 我和宋清朗相戀三年正压,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片责球。...
    茶點(diǎn)故事閱讀 40,001評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡焦履,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出棕诵,到底是詐尸還是另有隱情裁良,我是刑警寧澤,帶...
    沈念sama閱讀 35,723評論 5 346
  • 正文 年R本政府宣布校套,位于F島的核電站,受9級特大地震影響牧抵,放射性物質(zhì)發(fā)生泄漏笛匙。R本人自食惡果不足惜侨把,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,343評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望妹孙。 院中可真熱鬧秋柄,春花似錦、人聲如沸蠢正。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,919評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽嚣崭。三九已至笨触,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間雹舀,已是汗流浹背芦劣。 一陣腳步聲響...
    開封第一講書人閱讀 33,042評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留说榆,地道東北人虚吟。 一個(gè)月前我還...
    沈念sama閱讀 48,191評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像签财,于是被迫代替她去往敵國和親串慰。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,955評論 2 355

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

  • 代碼編譯的結(jié)果從本地機(jī)器碼轉(zhuǎn)變?yōu)樽止?jié)碼唱蒸,是存儲格式發(fā)展的一小步模庐,確實(shí)編譯語言發(fā)展的一大步。 虛擬機(jī)把描述類的數(shù)據(jù)從...
    胡二囧閱讀 956評論 0 0
  • 虛擬機(jī)把描述類的數(shù)據(jù)從Class文件加載到內(nèi)存油宜,并對數(shù)據(jù)進(jìn)行校驗(yàn)掂碱、轉(zhuǎn)換解析和初始化,最終形成可以被虛擬機(jī)直接使用的...
    丑人林宗己閱讀 567評論 0 2
  • 原文地址[http://blog.csdn.net/ns_code/article/details/1788158...
    期待現(xiàn)在閱讀 263評論 0 2
  • 1.加載慎冤,將二進(jìn)制字節(jié)流加載到方法區(qū),然后在java堆中實(shí)例化一個(gè)java.lang.Class類的對象2.驗(yàn)證:...
    蒸汽飛船閱讀 808評論 0 0
  • 上篇文章中疼燥,我們介紹了 .class 文件的結(jié)構(gòu),.class 文件只是一個(gè)靜態(tài)的文件蚁堤,那 JVM 是加載 .cl...
    lijiankun24閱讀 2,998評論 2 9