初識(shí)JVM-類加載器1

1.前言

每當(dāng)我們編寫一個(gè)Java程序的時(shí)候都會(huì)經(jīng)歷厌丑,編寫击奶,編譯,運(yùn)行的一個(gè)過(guò)程。編譯的過(guò)程是通過(guò)Java的編譯器來(lái)幫我們完成馏段,他幫我們把java文件編譯成class二進(jìn)制進(jìn)制文件轩拨,并保存在硬盤中,但是當(dāng)我們要運(yùn)行程序的時(shí)候院喜,我們需要將class文件加載進(jìn)內(nèi)存亡蓉,啟動(dòng)JVM虛擬機(jī),虛擬機(jī)幫我們開(kāi)啟一個(gè)線程喷舀,來(lái)執(zhí)行我們編寫的代碼砍濒,而將字節(jié)碼文件加載進(jìn)內(nèi)存的過(guò)程就是需要ClassLoader,即類加載器。
在介紹類加載器之前我們先看一段代碼硫麻。

class Singleton {
    private static Singleton singleton = new Singleton(); //1
    public static int counter1;                           //2
    public static int counter2 = 0;                       //3

    private Singleton() {
        counter1++;
        counter2++;
    }

    public static Singleton getInstance() {
        return singleton;
    }
}

public class ClassLoaderClient {
    public static void main(String[] args) {
        Singleton singleton = Singleton.getInstance();
        System.out.println("counter1 = " + singleton.counter1);
        System.out.println("counter2 = " + singleton.counter2);
    }
}

Singleton類很簡(jiǎn)單爸邢,聲明了3個(gè)靜態(tài)變量,對(duì)Singleton的構(gòu)造方法進(jìn)行了初始化拿愧,并且對(duì)Singleton進(jìn)行了單例化杠河。好讓我們思考一下在main方法中程序運(yùn)行的結(jié)果是什么?
很多朋友浇辜,可能會(huì)嗤之以鼻券敌,就會(huì)說(shuō),這還不簡(jiǎn)單柳洋,很顯然待诅,counter1,counter2 結(jié)果都為2⌒芰停可是結(jié)果真的是這樣嗎卑雁??我們看一下結(jié)果绪囱。

// 輸出結(jié)果
counter1 = 1
counter2 = 0

是不是出乎意料了序厉,嘿嘿,好玩的還在后面毕箍,我們將第1行代碼和第2,3行對(duì)調(diào),就像這樣道盏。

public static int counter1;                           
public static int counter2 = 0;                       
private static Singleton singleton = new Singleton(); 

當(dāng)我們把程序修改成這樣之后而柑,程序的運(yùn)行結(jié)果就成這樣了。

// 輸出結(jié)果
counter1 = 1
counter2 = 1

我知道大家心里肯定都充滿了疑惑荷逞,為什么僅僅是更改了幾行代碼媒咳,輸出結(jié)果就發(fā)生了改變呢?帶著這些疑惑种远,我們學(xué)習(xí)完下面的內(nèi)容涩澡,“類加載”的相關(guān)概念,這個(gè)問(wèn)題就是小菜一碟啦坠敷!

2.類加載的過(guò)程概述

一般的妙同,一個(gè)類的加載要經(jīng)過(guò)三個(gè)過(guò)程射富,即 加載 => 連接 => 初始化。而每個(gè)過(guò)程都需要做一些事情粥帚,保證類能夠正確的加載進(jìn)內(nèi)存胰耗,讓我們可以正確的使用對(duì)象。


類加載的過(guò)程.png
  • 1.加載
    查找并加載二進(jìn)制文件到內(nèi)存
  • 2.連接
    • 2.1驗(yàn)證:確保被加載類的正確性
    • 2.2準(zhǔn)備:為類的靜態(tài)變量(類變量)分配內(nèi)存芒涡,并為其初始化為默認(rèn)值柴灯,基本數(shù)據(jù)類型是其默認(rèn)值,引用數(shù)據(jù)類型是null。
    • 2.3解析:把類中的符號(hào)引用轉(zhuǎn)換為直接引用费尽。
  • 3.初始化
    為類的靜態(tài)變量賦予正確的初始值赠群。這里的初始值,和連接中的初始值旱幼,不是同一個(gè)初始值查描,這里的初始值,是我們自己為該靜態(tài)變量顯式的賦予初始值速警。
    public static int counter1 = 10 // 將10賦值給counter1就是顯示的初始化

3.類加載分析

3.1加載

類的加載指的是類加載器將類的.class文件中的二進(jìn)制數(shù)據(jù)讀入到內(nèi)存中叹誉,將其放在運(yùn)行時(shí)數(shù) 據(jù)區(qū)的方法區(qū)內(nèi),然后在堆區(qū)創(chuàng)建一個(gè) java.lang.Class對(duì)象闷旧,用來(lái)封裝類在方法區(qū)內(nèi)的數(shù)據(jù)結(jié)構(gòu)长豁,類的加載的最終產(chǎn)品是位于堆區(qū)中的 Class對(duì)象。Class對(duì)象封裝了類在方法區(qū)內(nèi)的數(shù)據(jù)結(jié)構(gòu) 忙灼,并且向Java程序員提供了訪問(wèn)方法區(qū)內(nèi) 的數(shù)據(jù)結(jié)構(gòu)的接口匠襟。Java中的反射機(jī)制就是操作堆內(nèi)存中的java.lang.Class對(duì)象。

3.2連接

類被加載后该园,就進(jìn)入連接階段酸舍。連接就是 將已經(jīng)讀入到內(nèi)存的類的二進(jìn)制數(shù)據(jù)合并 到虛擬機(jī)的運(yùn)行時(shí)環(huán)境中去。

3.2.1類的驗(yàn)證

驗(yàn)證就是對(duì)Class文件的語(yǔ)法,文法,格式規(guī)范進(jìn)行驗(yàn)證里初。放置惡意用戶對(duì)Class文件進(jìn)行修改啃勉,破壞程序的執(zhí)行。
驗(yàn)證主要包含以下幾個(gè)步驟双妨。

  • 1類文件的結(jié)構(gòu)檢查
    確保類文件遵從Java類文件的固定格式淮阐。
  • 2語(yǔ)義檢查
    確保類本身符合Java語(yǔ)言的語(yǔ)法規(guī)范,比如驗(yàn)證final的類不能被繼承刁品,final修飾的方法泣特,子類不能重寫等。
  • 3字節(jié)碼驗(yàn)證
    確保字節(jié)碼流可以被Java虛擬機(jī)安全地執(zhí)行挑随,字節(jié)碼流代表Java方法(包括實(shí)例方法和靜態(tài)方法),他是由被稱作操作嗎的單字節(jié)執(zhí)行組成的序列状您,每個(gè)操作碼后都跟隨一個(gè)或多個(gè)操作數(shù)(類似匯編語(yǔ)言)。字節(jié)碼驗(yàn)證步驟會(huì)檢查每個(gè)操作碼是否合法,即是否有著合法的操作數(shù)膏孟。
  • 4二進(jìn)制兼容性的驗(yàn)證
    確保相互引用的類之間的協(xié)調(diào)一致眯分,例如,Study類的getoStudy()方法調(diào)用Student里的studyEnglish()方法骆莹,Java虛擬機(jī)在驗(yàn)證Worker類的時(shí)候會(huì)檢查方法去內(nèi)是否存在Student類的StudyEnglish()方法颗搂,加入不存在(比如用Student類用Jdk1.6編譯,Study類Jdk1.5編譯)幕垦,就會(huì)拋出NoSuchMethodError錯(cuò)誤丢氢。

3.2.2類的準(zhǔn)備

在準(zhǔn)備階段,Java虛擬機(jī)為類的靜態(tài)變量分配內(nèi)存先改,并設(shè)置默認(rèn)的初始值疚察。例如下面的Sample類,在類的準(zhǔn)備階段仇奶,將int類型的靜態(tài)變量a分配4個(gè)子節(jié)的內(nèi)存空間貌嫡,并賦予默認(rèn)值0,為long類型的靜態(tài)變量b分配8個(gè)子節(jié)的內(nèi)存空間该溯,并賦予0

public class Sample {
  private static int a = 1;
  private static long b;
  static {
     b = 2;
  }
}

3.2.3類的連接

在類的解析階段岛抄,Java虛擬機(jī)會(huì)把類的而精致數(shù)據(jù)種的符號(hào)引用替換為直接引用。例如Study類的gotoStudy方法會(huì)引用Student的studyEnglish()方法

public void gotoStudy() {
  student.studyEnglish();
}

在Study類的二進(jìn)制數(shù)據(jù)中狈茉,包含對(duì)Student類studyEnglish()方法的符號(hào)引用夫椭,它由方法的全名和相關(guān)的描述符構(gòu)成,在解析階段氯庆,Java虛擬機(jī)會(huì)把這些符號(hào)引用用一個(gè)指針替換蹭秋,該指針指向Student類studyEnglish()方法在方法區(qū)內(nèi)的內(nèi)存位置,這個(gè)指針就是直接引用堤撵。

3.3初始化

在初始化階段仁讨,java虛擬機(jī)執(zhí)行類的初始化語(yǔ)句,為類的靜態(tài)變量賦予初始值实昨。在程序中靜態(tài)變量初始化由兩種途徑:(1)在靜態(tài)變量的聲明處進(jìn)行初始化 (2)在靜態(tài)代碼塊中進(jìn)行初始化洞豁。例如在以下代碼中靜態(tài)變量a,b就被顯示的初始化,而靜態(tài)變量c沒(méi)有被顯式初始化荒给,它將保持默認(rèn)值0族跛。

public class Sample {
  private static int a = 1;
  private static long b;
  private static long c;
  static {
     b = 2;
  }
}

3.3.1類初始化步驟

  1. 加入這個(gè)類未被加載和連接,那就先進(jìn)行加載和連接锐墙。
  2. 加入這個(gè)類存在直接的父類,并且這個(gè)父類沒(méi)有初始化长酗,那么就先初始化父類溪北。
  3. 假如類中存在初始化語(yǔ)句,那就依此執(zhí)行這些初始化語(yǔ)句。

3.3.2類初始化的時(shí)機(jī)

而在Java中Class文件的加載還是有條件的并不是,想怎么加載就怎么加載之拨,這樣的話可就亂了套了茉继。因此JVM對(duì)Class文件的加載時(shí)機(jī)做了說(shuō)明。

3.3.2.1Java程序?qū)︻惖氖褂梅譃閮煞N方式蚀乔。

  1. 主動(dòng)使用(6種方式)
    所有的Java虛擬機(jī)加載Class文件,必須在每個(gè)類或接口被Java程序“首次主動(dòng)使用”時(shí)才初始化他們烁竭。
    • 創(chuàng)建類的實(shí)例。
    • 初始化一個(gè)類的子類吉挣。
    • 訪問(wèn)某個(gè)類或接口的靜態(tài)變量派撕,或者對(duì)該靜態(tài)變量賦值
    • 調(diào)用類的靜態(tài)方法睬魂。
    • 反射,如 Class.forName("com.test.user")
    • Java虛擬機(jī)啟動(dòng)時(shí)被標(biāo)明為啟動(dòng)類的類,就是通過(guò)java命令執(zhí)行包含main方法的類终吼,如 java Test
// 1.創(chuàng)建類的實(shí)例
User user = new User();
        
// 2.初始化一個(gè)類的子類
Class Father {}
Class Son extends Father {}
Son son = new Son();
        
// 3.訪問(wèn)類/接口的靜態(tài)變量,或者對(duì)該靜態(tài)變量賦值
String var1 = StaticClassTest.COUNTER1;
        
// 4.調(diào)用類的靜態(tài)方法
StaticClassTest.method1();
        
// 5.反射
Class<?> aClass = Class.forName("com.test.jvm.AJvm.classLoaderSeq.context.Son");
  1. 被動(dòng)使用
    除了以上六種情況氯哮,其他使用Java類的方 式都被看作是對(duì)類的被動(dòng)使用际跪,都不會(huì)導(dǎo) 致類的初始化

3.3.2.2一些注意事項(xiàng)

  • 1.接口的初始化
    當(dāng)Java虛擬機(jī)初始化一個(gè)類的時(shí)候,要求它的父類都已經(jīng)被初始化喉钢,但這個(gè)規(guī)則不適用于接口姆打。

    • 在初始化一個(gè)類時(shí),并不會(huì)初始化它所實(shí)現(xiàn)的接口肠虽。
    • 在初始化一個(gè)接口的時(shí)候幔戏,并不會(huì)初始化它的父接口。

    因此舔痕,一個(gè)父接口并不會(huì)它的子接口或者實(shí)現(xiàn)類初始化而初始化评抚,只有程序首次使用特定接口的靜態(tài)變量。才會(huì)導(dǎo)致該接口的初始化伯复。

  • 2.編譯時(shí)常量
    當(dāng)一個(gè)類中變量被 final static 修飾成為靜態(tài)常量時(shí),我們?cè)偃ブ鲃?dòng)調(diào)用該靜態(tài)常量時(shí),類的初始化的過(guò)程就是另一番的結(jié)果慨代。

class Test1 {
    static final int cnt = 6 /3;
    static final int times = new Random().nextInt(100);
    static {
        System.out.println("Test Const ClassLoader!");
    }
}
public class ConstClassLoaderTest {
    public static void main(String[] args) {
        System.out.println("value=" + Test1.cnt);
    }
}

輸出結(jié)果value=2,根據(jù)我們前面學(xué)習(xí)的知識(shí)點(diǎn),應(yīng)對(duì)類進(jìn)行初始化啸如,也就是說(shuō)先輸出靜態(tài)代碼塊的內(nèi)容再輸出 value=2,因?yàn)閏nt被final修飾侍匙,因此程序的運(yùn)行結(jié)果會(huì)有些不一樣。
對(duì)于靜態(tài)常量cnt來(lái)說(shuō)叮雳,java在編譯階段就可以確定該變量的具體數(shù)值 因此不需要將該類進(jìn)內(nèi)存想暗。而我們把這種靜態(tài)變量叫做編譯時(shí)常量。
當(dāng)把代碼修改成這樣是程序的運(yùn)行結(jié)果又會(huì)不一樣帘不。

public class ConstClassLoaderTest {
    public static void main(String[] args) {
        System.out.println("value=" + Test1.times);
    }
}

運(yùn)行結(jié)果

Test Const ClassLoader!
value=41

對(duì)于靜態(tài)常量times來(lái)說(shuō),java在編譯階段無(wú)法確定該變量的具體數(shù)值,需要在運(yùn)行時(shí)才能確定说莫, 需要將該類加載進(jìn)內(nèi)存進(jìn)行,初始化后確定該常量的具體數(shù)值寞焙。

  • 3.只有當(dāng)程序訪問(wèn)的靜態(tài)變量或靜態(tài)方法確 實(shí)在當(dāng)前類或當(dāng)前接口中定義時(shí)储狭,才可以 認(rèn)為是對(duì)類或接口的主動(dòng)使用
    如何理解這句話呢互婿?我們還是看代碼說(shuō)話。
class Parent1 {
    static int cnt1 = 1;
    static {
        System.out.println("Parent1初始化!");
    }
    static void doSomeThing() {
        System.out.println("Parent1.doSomeThng()!");
    }
}

class Son1 extends Parent1 {
    static {
        System.out.println("Son1初始化辽狈!");
    }
}

public class TestClassLoader {
    public static void main(String[] args) {
        System.out.println(Son1.cnt1);
        Son1.doSomeThing();
    }
}

輸出結(jié)果

Parent1初始化!
cnt1=1
Parent1.doSomeThng()!

為什么Son1的靜態(tài)代碼塊沒(méi)有執(zhí)行呢慈参?
因?yàn)閏nt1是從父類繼承下來(lái)的。并非在當(dāng)前類(Son類)定義的靜態(tài)成員/方法,因此Son的靜態(tài)代碼不會(huì)執(zhí)行刮萌。

4.結(jié)果分析

看完了這些內(nèi)容我們?cè)俜治鲆粋€(gè)剛開(kāi)始的那個(gè)類的執(zhí)行結(jié)果驮配。

class Singleton {
    private static Singleton singleton = new Singleton(); //1
    public static int counter1;                           //2
    public static int counter2 = 0;                       //3

    private Singleton() {
        counter1++;
        counter2++;
    }

    public static Singleton getInstance() {
        return singleton;
    }
}

public class ClassLoaderClient {
    public static void main(String[] args) {
        Singleton singleton = Singleton.getInstance();
        System.out.println("counter1 = " + singleton.counter1);
        System.out.println("counter2 = " + singleton.counter2);
    }
}
  1. 由"java虛擬機(jī)會(huì)加載被聲明為啟動(dòng)類的類"這條規(guī)則可以知道,JVM啟動(dòng)時(shí)首先會(huì)把ClassLoaderClient類加載進(jìn)內(nèi)存着茸。
  2. 程序執(zhí)行ClassLoaderClient.main()方法的第一條語(yǔ)句Sington.getInstance()獲取Singtone類的一個(gè)唯一實(shí)例壮锻。但是getInstance()方法是靜態(tài)方法,所以JVM會(huì)將Sington類加載進(jìn)內(nèi)存元扔。會(huì)經(jīng)歷加載 => 連接 => 初始化
  3. [連接]中的[準(zhǔn)備階段]躯保,會(huì)對(duì)Sington中靜態(tài)變量!靜態(tài)變量!靜態(tài)變量!進(jìn)行默認(rèn)的初始化,賦值情況如下澎语。
private static Singleton singleton = null;
public static int counter1 = 0;
public static int counter2 = 0;  
  1. 然后在初始化階段對(duì)程序進(jìn)行默認(rèn)初始化途事,此時(shí)代碼中的第一行調(diào)用構(gòu)造函數(shù)對(duì)Sington實(shí)例進(jìn)行初始化。結(jié)果就是
public static int counter1 = 1;
public static int counter2 = 1;  
  1. 最后執(zhí)行第2擅羞,3行代碼,counter1未對(duì)其進(jìn)行賦值尸变,所以保持其構(gòu)造方法對(duì)它的賦值1,counter2 則進(jìn)行了顯式的賦值,此時(shí) counter2為0

因此最終結(jié)果是。

// 輸出結(jié)果
counter1 = 1
counter2 = 0

現(xiàn)在我們?cè)賮?lái)分析第二種情況减俏,將第1行代碼和第2召烂,3行代碼對(duì)調(diào)。

public static int counter1;                           
public static int counter2 = 0;                       
private static Singleton singleton = new Singleton(); 

其實(shí)前三步的結(jié)果是一樣的就是從第四部開(kāi)始有些不一樣了娃承。

  • 在初始化階段奏夫,類的初始化順序和靜態(tài)變量/靜態(tài)代碼的聲明順序是保持一致的,因此程序的執(zhí)行流程是這樣的历筝。
    1. counter1保持它的默認(rèn)初始值0
    2. counter2被顯式的賦值為0(注意:是初始化階段的賦值酗昼,并非準(zhǔn)備階段的默認(rèn)值)
    3. 調(diào)用new Singleton()構(gòu)造方法對(duì)counter1賦值為1,counter2賦值1

因此最終結(jié)果是

// 輸出結(jié)果
counter1 = 1
counter2 = 1
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末梳猪,一起剝皮案震驚了整個(gè)濱河市麻削,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌春弥,老刑警劉巖呛哟,帶你破解...
    沈念sama閱讀 212,454評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異匿沛,居然都是意外死亡扫责,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門逃呼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)公给,“玉大人借帘,你說(shuō)我怎么就攤上這事√暑恚” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 157,921評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵蔫缸,是天一觀的道長(zhǎng)腿准。 經(jīng)常有香客問(wèn)我,道長(zhǎng)拾碌,這世上最難降的妖魔是什么吐葱? 我笑而不...
    開(kāi)封第一講書人閱讀 56,648評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮校翔,結(jié)果婚禮上弟跑,老公的妹妹穿的比我還像新娘。我一直安慰自己防症,他們只是感情好孟辑,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,770評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著蔫敲,像睡著了一般饲嗽。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上奈嘿,一...
    開(kāi)封第一講書人閱讀 49,950評(píng)論 1 291
  • 那天貌虾,我揣著相機(jī)與錄音,去河邊找鬼裙犹。 笑死尽狠,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的叶圃。 我是一名探鬼主播袄膏,決...
    沈念sama閱讀 39,090評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼盗似!你這毒婦竟也來(lái)了哩陕?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 37,817評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤赫舒,失蹤者是張志新(化名)和其女友劉穎悍及,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體接癌,經(jīng)...
    沈念sama閱讀 44,275評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡心赶,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,592評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了缺猛。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片缨叫。...
    茶點(diǎn)故事閱讀 38,724評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡椭符,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出耻姥,到底是詐尸還是另有隱情销钝,我是刑警寧澤,帶...
    沈念sama閱讀 34,409評(píng)論 4 333
  • 正文 年R本政府宣布琐簇,位于F島的核電站萨脑,受9級(jí)特大地震影響沃于,放射性物質(zhì)發(fā)生泄漏峡蟋。R本人自食惡果不足惜项钮,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,052評(píng)論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望丈秩。 院中可真熱鬧盯捌,春花似錦、人聲如沸蘑秽。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,815評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)筷狼。三九已至瓶籽,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間埂材,已是汗流浹背塑顺。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,043評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留俏险,地道東北人严拒。 一個(gè)月前我還...
    沈念sama閱讀 46,503評(píng)論 2 361
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像竖独,于是被迫代替她去往敵國(guó)和親裤唠。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,627評(píng)論 2 350

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

  • 原文鏈接:http://iaspecwang.iteye.com/blog/1931043 一.概述 定義:虛擬機(jī)...
    晴天哥_王志閱讀 6,761評(píng)論 1 35
  • 代碼編譯的結(jié)果從本地機(jī)器碼轉(zhuǎn)變?yōu)樽止?jié)碼航瞭,是存儲(chǔ)格式發(fā)展的一小步,確實(shí)編譯語(yǔ)言發(fā)展的一大步坦辟。 虛擬機(jī)把描述類的數(shù)據(jù)從...
    胡二囧閱讀 950評(píng)論 0 0
  • 命運(yùn)不會(huì)虧欠誰(shuí)刊侯,看開(kāi)了,誰(shuí)的頭頂都有一汪藍(lán)天锉走;看淡了滨彻,誰(shuí)的心中都有一片花海藕届。只有春綠冬黃,你才能感受自然的交替亭饵;只...
    羅掌柜real閱讀 406評(píng)論 0 0
  • 早上7點(diǎn)多打電話給老爸休偶,告訴他我等下會(huì)去到他那里,修理下微信掉線辜羊。聽(tīng)到老爸歡喜的聲音:好的椅贱,我等著。心里好慶幸只冻,自...
    朱紅霞_7c4f閱讀 211評(píng)論 1 3
  • 今天星期日,做完作業(yè)后我給自己洗手帕计技,我先把手帕浸濕喜德,接著我給它擦上肥皂,然后揉一揉垮媒,再擰一下舍悯,再在清水里漂洗了下...
    趙麗麗丫閱讀 218評(píng)論 0 0