Java前期(靜態(tài))綁定與后期(動態(tài))綁定

為了知道靜態(tài)綁定和動態(tài)綁定的區(qū)別,我們先了解一下什么是綁定。綁定就是指引用與實際代碼之間的關(guān)聯(lián),比如說,當你引用一個變量的時候是由定義這個變量的代碼確定的。同樣的當你調(diào)用一個方法的時候,它會與這個方法的定義關(guān)聯(lián)起來。在Java里面方法綁定有兩種方式,一種叫靜態(tài)綁定,一種叫動態(tài)綁定。當一個方法被調(diào)用的時候程序?qū)嶋H的執(zhí)行和對象的創(chuàng)建有可能在編譯期確定,也可能在運行期。就像名字所說,靜態(tài)綁定有著靜態(tài)的本質(zhì),因此它發(fā)生在編譯期里,就好比根據(jù)編譯的結(jié)果你可以在代碼里清楚知道某方法的調(diào)用對應(yīng)的源碼在哪個class文件里面。

另一方面,當JVM開始執(zhí)行你的程序時動態(tài)綁定發(fā)生在運行期間。方法的調(diào)用被取決于實際的對象,這些對象的信息在編譯期里是不能得到的,因為對象的創(chuàng)建在運行期。因為在程序生命周期發(fā)生較晚,它也叫后期綁定。

那么他們最基本的不同就是一個使用變量引用類型發(fā)生在編譯期,一個使用實際對象發(fā)生在運行期。

前期綁定 vs 后期綁定

關(guān)于靜態(tài)綁定和動態(tài)綁定的區(qū)別有很多觀點,但是最重要的還是要看JVM怎么去使用。你是否有想過當有多個同名的方法的時候JVM是怎么確定要去調(diào)用哪個的?如果你知道方法重載(overloading)或者方法重寫(overriding)的話你應(yīng)該知道方法重名是怎么回事。JVM會根據(jù)靜態(tài)或動態(tài)綁定去尋找對應(yīng)的方法。

靜態(tài)和綁定的例子

在以下程序,你可以看到即使使用了靜態(tài)綁定,虛擬方法(virtual methods)并沒有綁定在編譯期,因為按我們想法會出現(xiàn)父類是會被調(diào)用的,但是事實上并不是。由于子類的方法被調(diào)用證明真實的對象在運行期被使用,因此動態(tài)綁定一般用于綁定虛擬方法。

public class Main {
    public static void main(String[] args) {
        // An example of static and dynamic binding in Java
        Insurance current = new CarInsurance();

        // dynamic binding based upon object
        int premium = current.premium();

        // static binding based upon class
        String category = current.category();

        System.out.println("premium : " + premium);
        System.out.println("category : " + category);

    }

    class Insurance{
        public static final int LOW = 100;
        public int premium(){
            return LOW;
        }
        public static String category(){
            return "Insurance";
        }
    }

    class CarInsurance extends Insurance{ 
        public static final int HIGH = 200; 
        public int premium(){ 
            return HIGH; 
        } 
        public static String category(){ 
            return "Car Insurance"; 
        } 
    } 
    
    //Output premium : 200 
    //category : Insurance

}

你可以看到當調(diào)用premium()方法的時候是執(zhí)行的是子類的方法,而當調(diào)用cateogry()方法的時候是執(zhí)行父類的方法。這是因為premium()是虛擬方法并且使用的是前期綁定來處理,而category()方法是一個靜態(tài)方法,在編譯期使用類名做靜態(tài)綁定來處理。

前期和后期綁定的區(qū)別總結(jié)

現(xiàn)在你知道和明白方法的調(diào)用是如何綁定的和靜態(tài)和動態(tài)的綁定是怎樣工作的(說的那么簡單我還真沒看明白),讓我們來回顧一下他們之間的一些重要的、關(guān)鍵的不同:

  1. 靜態(tài)綁定發(fā)生在編譯期而動態(tài)綁定發(fā)生在運行期
  2. 因為靜態(tài)綁定發(fā)生在程序生命周期較早階段,它也叫前期綁定。同樣動態(tài)綁定發(fā)生在程序?qū)嶋H運行中,所以也叫后期綁定。
  3. 靜態(tài)綁定一般用于方法重載,而動態(tài)綁定一般用于方法重寫。
  4. 同樣,靜態(tài)綁定可以用于私有的(private)、靜態(tài)的(static)和終態(tài)的(final)方法,因為他們不能被重寫和所有虛擬方法用動態(tài)綁定來解決。
  5. 真實的對象不能用于靜態(tài)綁定,相反,類型信息比如變量的類型可以用于本地的方法。另一方面,動態(tài)綁定用一個真是的對象去找到那個真正的方法的。

這里有個很好的練習是基于靜態(tài)和動態(tài)綁定的,答案是?

triky Java Interview Questions in Java.png

原文地址: Difference between early (static) binding vs late (dynamic) binding in Java

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

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

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,527評論 19 139
  • 從三月份找實習到現(xiàn)在,面了一些公司,掛了不少,但最終還是拿到小米、百度、阿里、京東、新浪、CVTE、樂視家的研發(fā)崗...
    時芥藍閱讀 42,783評論 11 349
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,636評論 18 399
  • 程序綁定的概念: 綁定指的是一個方法的調(diào)用與方法所在的類(方法主體)關(guān)聯(lián)起來。對java來說,綁定分為靜態(tài)綁定和動...
    Mr_chong閱讀 1,388評論 0 7
  • 本文為菜鳥窩作者蔣志碧的連載?!皬?0 開始開發(fā)一款直播 APP ”系列來聊聊時下最火的直播 APP,如何完整的實...
    菜鳥窩閱讀 700評論 1 3

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