12.JVM學(xué)習(xí)筆記_字節(jié)碼知識(shí)點(diǎn)整理

字節(jié)碼知識(shí)點(diǎn)整理

對(duì)于Java類中的每個(gè)實(shí)例方法(非static方法),其在編譯后所生成的字節(jié)碼當(dāng)中,方法參數(shù)的數(shù)量總是會(huì)比源代碼中方法參數(shù)的數(shù)量多一個(gè)(this),它位于方法的第一個(gè)參數(shù)位置處;這樣,我們就可以在Java的實(shí)例方法中使用this來(lái)去訪問(wèn)當(dāng)前對(duì)象屬性以及其他方法。

這個(gè)操作是在編譯期間完成的,即由javac編譯器在編譯的時(shí)候?qū)?duì)this的訪問(wèn)轉(zhuǎn)化為對(duì)一個(gè)普通實(shí)例方法參數(shù)的訪問(wèn),接下來(lái)在運(yùn)行期間,由JVM在調(diào)用實(shí)例方法時(shí),自動(dòng)向?qū)嵗椒▊魅朐搕his參數(shù)。所以,在實(shí)例方法的局部變量表中,至少會(huì)有一個(gè)指向當(dāng)前對(duì)象的局部變量。

Java字節(jié)碼對(duì)于異常的處理方式:

1.統(tǒng)一采用異常表的方式來(lái)對(duì)異常進(jìn)行處理。
2.在jdk1.4.2之前的版本中,并不是使用異常表的方式來(lái)對(duì)異常進(jìn)行處理的,而是采用特定的指令方式。
3.當(dāng)異常處理存在finally語(yǔ)句塊時(shí),現(xiàn)代化的JVM采取的處理方式是將finally語(yǔ)句塊的字節(jié)碼拼接到每一個(gè)catch塊后面,換句話說(shuō),程序中存在多少個(gè)catch塊,就會(huì)在每一個(gè)catch塊后面重復(fù)多少個(gè)finally語(yǔ)句塊的字節(jié)碼。

棧幀(stack frame)

棧幀是一種用于幫助虛擬機(jī)執(zhí)行方法調(diào)用與方法執(zhí)行的數(shù)據(jù)結(jié)構(gòu)。

棧幀本身是一種數(shù)據(jù)結(jié)構(gòu),封裝了方法的局部變量表、動(dòng)態(tài)鏈接信息,方法的返回地址以及操作數(shù)棧等信息。

符號(hào)引用,直接引用

有些符號(hào)引用是在類加載階段或是第一次使用時(shí)就會(huì)轉(zhuǎn)換為直接引用,這種轉(zhuǎn)換叫做靜態(tài)解析;另外一些符號(hào)引用則是在每次運(yùn)行期轉(zhuǎn)換為直接引用,這種轉(zhuǎn)換叫做動(dòng)態(tài)鏈接,這體現(xiàn)為Java的多態(tài)性。

invokeinterface:調(diào)用接口中的方法,實(shí)際上是在運(yùn)行期決定的,決定到底調(diào)用實(shí)現(xiàn)該接口的哪個(gè)對(duì)象的特定方法。
invokestatic:調(diào)用靜態(tài)方法。
invokespecial:調(diào)用自己的私有方法、構(gòu)造方法(<init>)以及父類的方法。
invokevirtual:調(diào)用虛方法,運(yùn)行期動(dòng)態(tài)查找的過(guò)程。
invokedynamic:動(dòng)態(tài)調(diào)用方法。

靜態(tài)解析的4種情形:

1.靜態(tài)方法
2.父類方法
3.構(gòu)造方法
4.私有方法

以上4類方法稱作非虛方法,他們是在類加載階段就可以將符號(hào)引用轉(zhuǎn)換為直接引用。

方法的靜態(tài)分派:

Grandpa g1 = new Grandpa();

以上代碼,g1的靜態(tài)類型是Grandpa,而g1的實(shí)際類型(真正指向的類型)是Father。

我們可以得出這樣一個(gè)結(jié)論:變量的靜態(tài)類型是不會(huì)發(fā)生變化的,而變量的實(shí)際類型則是可以發(fā)生變化的(多態(tài)的一種體現(xiàn)),實(shí)際類型是在運(yùn)行期方可確定。

示例代碼:

public class MyTest5 {

    //方法重載,是一種靜態(tài)的行為,編譯器就可以完全確定。
    public void test(Grandpa grandpa) {
        System.out.println("grandpa");
    }

    public void test(Father father) {
        System.out.println("father");
    }

    public void test(Son son) {
        System.out.println("son");
    }

    public static void main(String[] args) {
        Grandpa g1 = new Father();
        Grandpa g2 = new Son();

        MyTest5 myTest5 = new MyTest5();

        myTest5.test(g1);
        myTest5.test(g2);
    }
}


class Grandpa {

}

class Father extends Grandpa {

}

class Son extends Father {

}

方法的動(dòng)態(tài)分派

方法的動(dòng)態(tài)分派涉及到一個(gè)重要概念:方法接受者。

invokevirtual字節(jié)碼指令單多態(tài)查找流程
比較方法重載(overload)與方法重寫(overwrite),我們可以得到這樣的結(jié)論:
方法重載是靜態(tài)的,是編譯期行為;方法重寫是動(dòng)態(tài)的,事運(yùn)行期行為。

示例代碼

public class MyTest6 {

    public static void main(String[] args) {
        Fruit apple = new Apple();

        Fruit orange = new Orange();

        apple.test();

        orange.test();

        apple = new Orange();

        apple.test();
    }
}

class Fruit{
    public void test(){
        System.out.println("Fruit");
    }
}

class Apple extends Fruit{

    @Override
    public void test() {
        System.out.println("Apple");
    }
}

class Orange extends  Fruit{
    @Override
    public void test() {
        System.out.println("Orange");
    }
}

針對(duì)于方法調(diào)用動(dòng)態(tài)分派的過(guò)程,虛擬機(jī)會(huì)在類的方法區(qū)建立一個(gè)虛方法表的數(shù)據(jù)結(jié)構(gòu)(virtual method table, vtable)
針對(duì)于invokeinterface指令來(lái)說(shuō),虛擬機(jī)會(huì)建立一個(gè)叫做接口方法表的數(shù)據(jù)結(jié)構(gòu)(interface method table,itable)

示例代碼:

public class MyTest7 {

    public static void main(String[] args) {
        Animal animal = new Animal();
        Animal dog = new Dog();

        animal.test("hello");
        dog.test(new Date());
    }

}

class Animal {
    public void test(String str) {
        System.out.println("animal str");
    }

    public void test(Date date) {
        System.out.println("animal date");
    }
}

class Dog extends Animal {
    @Override
    public void test(String str) {
        System.out.println("dog str");
    }

    @Override
    public void test(Date date) {
        System.out.println("dog date");
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • “大人,他已經(jīng)斷氣了。”一個(gè)官兵諂媚地笑著,看著不成人形的錢巖禮對(duì)著王守義說(shuō)道。 “哼!倒挺能堅(jiān)持!” “大人,只...
    竹曳的雷厲風(fēng)行閱讀 306評(píng)論 0 0
  • 三件事: (1)閱讀《必然》,100頁(yè)(得到電子書版) (2)囚徒健身半個(gè)小時(shí) (3)寫一篇說(shuō)理性文章 小確幸 在...
    咖飛的白閱讀 221評(píng)論 0 0

友情鏈接更多精彩內(nèi)容