Java動態(tài)綁定機(jī)制

前言

上班時間,正在互聯(lián)網(wǎng)暢游中

忽然發(fā)現(xiàn)網(wǎng)頁中出現(xiàn)了個名詞 “java的動態(tài)綁定”, 頓感疑惑, 于是問了周邊的同事

同事們商量好了一樣, 統(tǒng)一回復(fù) “沒聽過”!

求知欲爆棚的咸魚君只能自己研究

概念

什么叫綁定?

常識中, 綁定就是產(chǎn)生關(guān)聯(lián)的意思, 程序的世界也差不多是這個意思.

不妨換個問題

當(dāng)你想調(diào)用某個類的某個方法時, Java如何知道這個類和這個方法之間的關(guān)系的?

這就主要?dú)w功于Java的綁定機(jī)制了.

在Java中, 綁定分為兩種

  • 靜態(tài)綁定(前期綁定)

  • 動態(tài)綁定(后期綁定)

靜態(tài)綁定

在程序執(zhí)行前,方法已經(jīng)被綁定, 靜態(tài)綁定發(fā)生在編譯時期,也就是在編譯的時候我們就知道這個方法和類之間的關(guān)系.

在Java中, private static 和 final 方法都是靜態(tài)綁定.

動態(tài)綁定

Java是一門面向?qū)ο蟮木幊陶Z言, 優(yōu)勢就在于支持多態(tài).

多態(tài)的概念我們一句話解釋下: 子類繼承了父類, 并重寫了父類的方法.

多態(tài)的特性而引起了一個問題:

class Parent {
    void say() {
        System.out.println("Parent.say()");
  }
    void run() {
        System.out.println("Parent.run()");
  }
}
 
class Child extends Parent {
    void say() {
        System.out.println("Child.say()");
    }
}

//父類引用指向子類對象, 向上轉(zhuǎn)型
Parent  p = new Child();
p.say();
p.run();

此時p.say();p.run();輸出啥?

理論上講, p是個Parent對象, 那應(yīng)該是調(diào)用Parent的say()和run();
但是實(shí)際上我們期待的結(jié)果是調(diào)用Child對象的say()和run();

于是引出了動態(tài)綁定的概念

調(diào)用子類型對象的一個虛方法(非private,final or static), 編譯器將無法找到真正需要調(diào)用的方法, 因?yàn)樗赡苁嵌x在父類型中的方法,也可能是在子類型中被重寫的方法.
這種情形,只能在運(yùn)行時進(jìn)行解析,因?yàn)橹挥性谶\(yùn)行時期,才能明確具體的對象到底是什么.

動態(tài)綁定體現(xiàn)了Java的繼承與多態(tài),在繼承鏈中,JVM一直沿著繼承鏈動態(tài)找到帶有該方法的實(shí)現(xiàn).

不難看出, 最終輸出結(jié)果是

Child.say()    //子類重寫
Parent.run()    //子類未重寫, 根據(jù)繼承鏈找到了父類實(shí)現(xiàn)

注意點(diǎn)

理解了動態(tài)綁定的概念, 我們繼續(xù)拓展,下面這段代碼輸出啥

class Parent {
    int age = 60;
}
 
class Child extends Parent {
     int age = 20;
}

Parent p = new Child();
System.out.println("age = " + p.age);

此時輸出的age是Child對象的還是Parent對象的?

我們的期望肯定是輸出Child對象的20

但實(shí)際

age = 60

為什么呢? 說好的動態(tài)綁定呢?!

這就得強(qiáng)調(diào)下動態(tài)綁定的第二個特性了

  1. 當(dāng)調(diào)用對象方法的時候,該方法會和該對象的內(nèi)存地址/運(yùn)行類型(也就是與運(yùn)行類型)綁定
  2. 當(dāng)調(diào)用對象屬性時,沒有動態(tài)綁定機(jī)制,哪里聲明,哪里使用

看到這里, 動態(tài)綁定算是理解了.

不妨結(jié)合下面這段代碼來加深下理解

class Parent {
    int age = 60;
    int getAge() {
        return age;
    }
}
 
class Child extends Parent {
     int age = 20;
     int getAge() {
        return age;
    }
}

Parent p = new Child();
System.out.println("age = " + p.age);
System.out.println("age = " + p.getAge());

請關(guān)注我的訂閱號

訂閱號.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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

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